From 31c9070d270be764b94847df5b89ddc79cbd7be0 Mon Sep 17 00:00:00 2001 From: Lujiang Xue Date: Wed, 28 Feb 2018 08:46:08 -0800 Subject: [PATCH 001/701] improve car appsPermission view Fixes: 73127860 Test: deployed to head unit and test Change-Id: I86744f7901c696bf04201840164206c8895b47b9 --- res/drawable/ic_arrow_back.xml | 30 +++++++++ res/layout/car_app_permissions.xml | 61 +++++++++++++++++++ res/values/themes.xml | 4 ++ .../ui/ManagePermissionsActivity.java | 8 +-- .../ui/auto/AppPermissionsFragment.java | 4 +- .../auto/GrantPermissionsAutoViewHandler.java | 2 +- 6 files changed, 103 insertions(+), 6 deletions(-) create mode 100644 res/drawable/ic_arrow_back.xml create mode 100644 res/layout/car_app_permissions.xml diff --git a/res/drawable/ic_arrow_back.xml b/res/drawable/ic_arrow_back.xml new file mode 100644 index 000000000..81da87fd1 --- /dev/null +++ b/res/drawable/ic_arrow_back.xml @@ -0,0 +1,30 @@ + + + + + + diff --git a/res/layout/car_app_permissions.xml b/res/layout/car_app_permissions.xml new file mode 100644 index 000000000..b83526404 --- /dev/null +++ b/res/layout/car_app_permissions.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + diff --git a/res/values/themes.xml b/res/values/themes.xml index a88674aa5..649b30308 100644 --- a/res/values/themes.xml +++ b/res/values/themes.xml @@ -21,6 +21,10 @@ parent="@android:style/Theme.DeviceDefault.Settings"> + + - - - - - - - - diff --git a/res/values/themes.xml b/res/values/themes.xml index 3ddb6a7a9..cd76ea600 100644 --- a/res/values/themes.xml +++ b/res/values/themes.xml @@ -39,25 +39,8 @@ @*android:bool/config_closeDialogWhenTouchOutside - - - - - - - diff --git a/src/android/support/wearable/view/AcceptDenyDialog.java b/src/android/support/wearable/view/AcceptDenyDialog.java index f2129b8f4..933f1b38b 100644 --- a/src/android/support/wearable/view/AcceptDenyDialog.java +++ b/src/android/support/wearable/view/AcceptDenyDialog.java @@ -28,7 +28,7 @@ import android.widget.ImageView; import android.widget.Space; import android.widget.TextView; -import com.android.packageinstaller.R; +import com.android.permissioncontroller.R; /** * A dialog to display a title, a message, and/or an icon with a positive and a negative button. diff --git a/src/android/support/wearable/view/CircledImageView.java b/src/android/support/wearable/view/CircledImageView.java index 0ae344663..2a18f10c6 100644 --- a/src/android/support/wearable/view/CircledImageView.java +++ b/src/android/support/wearable/view/CircledImageView.java @@ -37,9 +37,8 @@ import android.util.AttributeSet; import android.view.View; import java.util.Objects; -import com.android.packageinstaller.R; -import com.android.packageinstaller.R; +import com.android.permissioncontroller.R; /** * An image view surrounded by a circle. diff --git a/src/com/android/packageinstaller/DeleteStagedFileOnResult.java b/src/com/android/packageinstaller/DeleteStagedFileOnResult.java deleted file mode 100644 index 399cf1f5e..000000000 --- a/src/com/android/packageinstaller/DeleteStagedFileOnResult.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 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.packageinstaller; - -import android.annotation.Nullable; -import android.app.Activity; -import android.content.Intent; -import android.os.Bundle; - -import java.io.File; - -/** - * Trampoline activity. Calls PackageInstallerActivity and deletes staged install file onResult. - */ -public class DeleteStagedFileOnResult extends Activity { - @Override - protected void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - if (savedInstanceState == null) { - Intent installIntent = new Intent(getIntent()); - installIntent.setClass(this, PackageInstallerActivity.class); - - installIntent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); - startActivityForResult(installIntent, 0); - } - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - File sourceFile = new File(getIntent().getData().getPath()); - sourceFile.delete(); - - setResult(resultCode, data); - finish(); - } -} diff --git a/src/com/android/packageinstaller/EventResultPersister.java b/src/com/android/packageinstaller/EventResultPersister.java deleted file mode 100644 index 0e62889c5..000000000 --- a/src/com/android/packageinstaller/EventResultPersister.java +++ /dev/null @@ -1,353 +0,0 @@ -/* - * 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. - */ - -package com.android.packageinstaller; - -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageInstaller; -import android.os.AsyncTask; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import android.util.AtomicFile; -import android.util.Log; -import android.util.SparseArray; -import android.util.Xml; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; -import org.xmlpull.v1.XmlSerializer; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.nio.charset.StandardCharsets; - -/** - * Persists results of events and calls back observers when a matching result arrives. - */ -class EventResultPersister { - private static final String LOG_TAG = EventResultPersister.class.getSimpleName(); - - /** Id passed to {@link #addObserver(int, EventResultObserver)} to generate new id */ - static final int GENERATE_NEW_ID = Integer.MIN_VALUE; - - /** - * The extra with the id to set in the intent delivered to - * {@link #onEventReceived(Context, Intent)} - */ - static final String EXTRA_ID = "EventResultPersister.EXTRA_ID"; - - /** Persisted state of this object */ - private final AtomicFile mResultsFile; - - private final Object mLock = new Object(); - - /** Currently stored but not yet called back results (install id -> status, status message) */ - private final SparseArray mResults = new SparseArray<>(); - - /** Currently registered, not called back observers (install id -> observer) */ - private final SparseArray mObservers = new SparseArray<>(); - - /** Always increasing counter for install event ids */ - private int mCounter; - - /** If a write that will persist the state is scheduled */ - private boolean mIsPersistScheduled; - - /** If the state was changed while the data was being persisted */ - private boolean mIsPersistingStateValid; - - /** - * @return a new event id. - */ - public int getNewId() throws OutOfIdsException { - synchronized (mLock) { - if (mCounter == Integer.MAX_VALUE) { - throw new OutOfIdsException(); - } - - mCounter++; - writeState(); - - return mCounter - 1; - } - } - - /** Call back when a result is received. Observer is removed when onResult it called. */ - interface EventResultObserver { - void onResult(int status, int legacyStatus, @Nullable String message); - } - - /** - * Progress parser to the next element. - * - * @param parser The parser to progress - */ - private static void nextElement(@NonNull XmlPullParser parser) - throws XmlPullParserException, IOException { - int type; - do { - type = parser.next(); - } while (type != XmlPullParser.START_TAG && type != XmlPullParser.END_DOCUMENT); - } - - /** - * Read an int attribute from the current element - * - * @param parser The parser to read from - * @param name The attribute name to read - * - * @return The value of the attribute - */ - private static int readIntAttribute(@NonNull XmlPullParser parser, @NonNull String name) { - return Integer.parseInt(parser.getAttributeValue(null, name)); - } - - /** - * Read an String attribute from the current element - * - * @param parser The parser to read from - * @param name The attribute name to read - * - * @return The value of the attribute or null if the attribute is not set - */ - private static String readStringAttribute(@NonNull XmlPullParser parser, @NonNull String name) { - return parser.getAttributeValue(null, name); - } - - /** - * Read persisted state. - * - * @param resultFile The file the results are persisted in - */ - EventResultPersister(@NonNull File resultFile) { - mResultsFile = new AtomicFile(resultFile); - mCounter = GENERATE_NEW_ID + 1; - - try (FileInputStream stream = mResultsFile.openRead()) { - XmlPullParser parser = Xml.newPullParser(); - parser.setInput(stream, StandardCharsets.UTF_8.name()); - - nextElement(parser); - while (parser.getEventType() != XmlPullParser.END_DOCUMENT) { - String tagName = parser.getName(); - if ("results".equals(tagName)) { - mCounter = readIntAttribute(parser, "counter"); - } else if ("result".equals(tagName)) { - int id = readIntAttribute(parser, "id"); - int status = readIntAttribute(parser, "status"); - int legacyStatus = readIntAttribute(parser, "legacyStatus"); - String statusMessage = readStringAttribute(parser, "statusMessage"); - - if (mResults.get(id) != null) { - throw new Exception("id " + id + " has two results"); - } - - mResults.put(id, new EventResult(status, legacyStatus, statusMessage)); - } else { - throw new Exception("unexpected tag"); - } - - nextElement(parser); - } - } catch (Exception e) { - mResults.clear(); - writeState(); - } - } - - /** - * Add a result. If the result is an pending user action, execute the pending user action - * directly and do not queue a result. - * - * @param context The context the event was received in - * @param intent The intent the activity received - */ - void onEventReceived(@NonNull Context context, @NonNull Intent intent) { - int status = intent.getIntExtra(PackageInstaller.EXTRA_STATUS, 0); - - if (status == PackageInstaller.STATUS_PENDING_USER_ACTION) { - context.startActivity(intent.getParcelableExtra(Intent.EXTRA_INTENT)); - - return; - } - - int id = intent.getIntExtra(EXTRA_ID, 0); - String statusMessage = intent.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE); - int legacyStatus = intent.getIntExtra(PackageInstaller.EXTRA_LEGACY_STATUS, 0); - - EventResultObserver observerToCall = null; - synchronized (mLock) { - int numObservers = mObservers.size(); - for (int i = 0; i < numObservers; i++) { - if (mObservers.keyAt(i) == id) { - observerToCall = mObservers.valueAt(i); - mObservers.removeAt(i); - - break; - } - } - - if (observerToCall != null) { - observerToCall.onResult(status, legacyStatus, statusMessage); - } else { - mResults.put(id, new EventResult(status, legacyStatus, statusMessage)); - writeState(); - } - } - } - - /** - * Persist current state. The persistence might be delayed. - */ - private void writeState() { - synchronized (mLock) { - mIsPersistingStateValid = false; - - if (!mIsPersistScheduled) { - mIsPersistScheduled = true; - - AsyncTask.execute(() -> { - int counter; - SparseArray results; - - while (true) { - // Take snapshot of state - synchronized (mLock) { - counter = mCounter; - results = mResults.clone(); - mIsPersistingStateValid = true; - } - - FileOutputStream stream = null; - try { - stream = mResultsFile.startWrite(); - XmlSerializer serializer = Xml.newSerializer(); - serializer.setOutput(stream, StandardCharsets.UTF_8.name()); - serializer.startDocument(null, true); - serializer.setFeature( - "http://xmlpull.org/v1/doc/features.html#indent-output", true); - serializer.startTag(null, "results"); - serializer.attribute(null, "counter", Integer.toString(counter)); - - int numResults = results.size(); - for (int i = 0; i < numResults; i++) { - serializer.startTag(null, "result"); - serializer.attribute(null, "id", - Integer.toString(results.keyAt(i))); - serializer.attribute(null, "status", - Integer.toString(results.valueAt(i).status)); - serializer.attribute(null, "legacyStatus", - Integer.toString(results.valueAt(i).legacyStatus)); - if (results.valueAt(i).message != null) { - serializer.attribute(null, "statusMessage", - results.valueAt(i).message); - } - serializer.endTag(null, "result"); - } - - serializer.endTag(null, "results"); - serializer.endDocument(); - - mResultsFile.finishWrite(stream); - } catch (IOException e) { - if (stream != null) { - mResultsFile.failWrite(stream); - } - - Log.e(LOG_TAG, "error writing results", e); - mResultsFile.delete(); - } - - // Check if there was changed state since we persisted. If so, we need to - // persist again. - synchronized (mLock) { - if (mIsPersistingStateValid) { - mIsPersistScheduled = false; - break; - } - } - } - }); - } - } - } - - /** - * Add an observer. If there is already an event for this id, call back inside of this call. - * - * @param id The id the observer is for or {@code GENERATE_NEW_ID} to generate a new one. - * @param observer The observer to call back. - * - * @return The id for this event - */ - int addObserver(int id, @NonNull EventResultObserver observer) - throws OutOfIdsException { - synchronized (mLock) { - int resultIndex = -1; - - if (id == GENERATE_NEW_ID) { - id = getNewId(); - } else { - resultIndex = mResults.indexOfKey(id); - } - - // Check if we can instantly call back - if (resultIndex >= 0) { - EventResult result = mResults.valueAt(resultIndex); - - observer.onResult(result.status, result.legacyStatus, result.message); - mResults.removeAt(resultIndex); - writeState(); - } else { - mObservers.put(id, observer); - } - } - - - return id; - } - - /** - * Remove a observer. - * - * @param id The id the observer was added for - */ - void removeObserver(int id) { - synchronized (mLock) { - mObservers.delete(id); - } - } - - /** - * The status from an event. - */ - private class EventResult { - public final int status; - public final int legacyStatus; - @Nullable public final String message; - - private EventResult(int status, int legacyStatus, @Nullable String message) { - this.status = status; - this.legacyStatus = legacyStatus; - this.message = message; - } - } - - class OutOfIdsException extends Exception {} -} diff --git a/src/com/android/packageinstaller/InstallEventReceiver.java b/src/com/android/packageinstaller/InstallEventReceiver.java deleted file mode 100644 index b7d32e9dc..000000000 --- a/src/com/android/packageinstaller/InstallEventReceiver.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * 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. - */ - -package com.android.packageinstaller; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import androidx.annotation.NonNull; - -/** - * Receives install events and perists them using a {@link EventResultPersister}. - */ -public class InstallEventReceiver extends BroadcastReceiver { - private static final Object sLock = new Object(); - private static EventResultPersister sReceiver; - - /** - * Get the event receiver persisting the results - * - * @return The event receiver. - */ - @NonNull private static EventResultPersister getReceiver(@NonNull Context context) { - synchronized (sLock) { - if (sReceiver == null) { - sReceiver = new EventResultPersister( - TemporaryFileManager.getInstallStateFile(context)); - } - } - - return sReceiver; - } - - @Override - public void onReceive(Context context, Intent intent) { - getReceiver(context).onEventReceived(context, intent); - } - - /** - * Add an observer. If there is already an event for this id, call back inside of this call. - * - * @param context A context of the current app - * @param id The id the observer is for or {@code GENERATE_NEW_ID} to generate a new one. - * @param observer The observer to call back. - * - * @return The id for this event - */ - static int addObserver(@NonNull Context context, int id, - @NonNull EventResultPersister.EventResultObserver observer) - throws EventResultPersister.OutOfIdsException { - return getReceiver(context).addObserver(id, observer); - } - - /** - * Remove a observer. - * - * @param context A context of the current app - * @param id The id the observer was added for - */ - static void removeObserver(@NonNull Context context, int id) { - getReceiver(context).removeObserver(id); - } -} diff --git a/src/com/android/packageinstaller/InstallFailed.java b/src/com/android/packageinstaller/InstallFailed.java deleted file mode 100644 index 56dc71d5f..000000000 --- a/src/com/android/packageinstaller/InstallFailed.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * 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. - */ - -package com.android.packageinstaller; - -import android.app.Activity; -import android.app.AlertDialog; -import android.app.Dialog; -import android.app.DialogFragment; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageInstaller; -import android.content.pm.PackageManager; -import android.net.Uri; -import android.os.Bundle; -import androidx.annotation.Nullable; -import android.util.Log; -import android.widget.TextView; - -import java.io.File; - -/** - * Installation failed: Return status code to the caller or display failure UI to user - */ -public class InstallFailed extends Activity { - private static final String LOG_TAG = InstallFailed.class.getSimpleName(); - - /** Label of the app that failed to install */ - private CharSequence mLabel; - - /** - * Convert an package installer status code into the user friendly label. - * - * @param statusCode The status code from the package installer. - * - * @return The user friendly label for the status code - */ - private int getExplanationFromErrorCode(int statusCode) { - Log.d(LOG_TAG, "Installation status code: " + statusCode); - - switch (statusCode) { - case PackageInstaller.STATUS_FAILURE_BLOCKED: - return R.string.install_failed_blocked; - case PackageInstaller.STATUS_FAILURE_CONFLICT: - return R.string.install_failed_conflict; - case PackageInstaller.STATUS_FAILURE_INCOMPATIBLE: - return R.string.install_failed_incompatible; - case PackageInstaller.STATUS_FAILURE_INVALID: - return R.string.install_failed_invalid_apk; - default: - return R.string.install_failed; - } - } - - @Override - protected void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - int statusCode = getIntent().getIntExtra(PackageInstaller.EXTRA_STATUS, - PackageInstaller.STATUS_FAILURE); - - if (getIntent().getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false)) { - int legacyStatus = getIntent().getIntExtra(PackageInstaller.EXTRA_LEGACY_STATUS, - PackageManager.INSTALL_FAILED_INTERNAL_ERROR); - - // Return result if requested - Intent result = new Intent(); - result.putExtra(Intent.EXTRA_INSTALL_RESULT, legacyStatus); - setResult(Activity.RESULT_FIRST_USER, result); - finish(); - } else { - Intent intent = getIntent(); - ApplicationInfo appInfo = intent - .getParcelableExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO); - Uri packageURI = intent.getData(); - - setContentView(R.layout.install_failed); - - // Set header icon and title - PackageUtil.AppSnippet as; - PackageManager pm = getPackageManager(); - - if ("package".equals(packageURI.getScheme())) { - as = new PackageUtil.AppSnippet(pm.getApplicationLabel(appInfo), - pm.getApplicationIcon(appInfo)); - } else { - final File sourceFile = new File(packageURI.getPath()); - as = PackageUtil.getAppSnippet(this, appInfo, sourceFile); - } - - // Store label for dialog - mLabel = as.label; - - PackageUtil.initSnippetForNewApp(this, as, R.id.app_snippet); - - // Show out of space dialog if needed - if (statusCode == PackageInstaller.STATUS_FAILURE_STORAGE) { - (new OutOfSpaceDialog()).show(getFragmentManager(), "outofspace"); - } - - // Get status messages - ((TextView) findViewById(R.id.simple_status)).setText( - getExplanationFromErrorCode(statusCode)); - - // Set up "done" button - findViewById(R.id.done_button).setOnClickListener(view -> finish()); - } - } - - /** - * Dialog shown when we ran out of space during installation. This contains a link to the - * "manage applications" settings page. - */ - public static class OutOfSpaceDialog extends DialogFragment { - private InstallFailed mActivity; - - @Override - public void onAttach(Context context) { - super.onAttach(context); - - mActivity = (InstallFailed) context; - } - - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - return new AlertDialog.Builder(mActivity) - .setTitle(R.string.out_of_space_dlg_title) - .setMessage(getString(R.string.out_of_space_dlg_text, mActivity.mLabel)) - .setPositiveButton(R.string.manage_applications, (dialog, which) -> { - // launch manage applications - Intent intent = new Intent("android.intent.action.MANAGE_PACKAGE_STORAGE"); - startActivity(intent); - mActivity.finish(); - }) - .setNegativeButton(R.string.cancel, (dialog, which) -> mActivity.finish()) - .create(); - } - - @Override - public void onCancel(DialogInterface dialog) { - super.onCancel(dialog); - - mActivity.finish(); - } - } -} diff --git a/src/com/android/packageinstaller/InstallInstalling.java b/src/com/android/packageinstaller/InstallInstalling.java deleted file mode 100755 index 22b1336c2..000000000 --- a/src/com/android/packageinstaller/InstallInstalling.java +++ /dev/null @@ -1,413 +0,0 @@ -/* - * 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. - */ - -package com.android.packageinstaller; - -import static android.content.pm.PackageInstaller.SessionParams.UID_UNKNOWN; - -import android.app.Activity; -import android.app.PendingIntent; -import android.content.Intent; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageInstaller; -import android.content.pm.PackageManager; -import android.content.pm.PackageParser; -import android.net.Uri; -import android.os.AsyncTask; -import android.os.Bundle; -import android.util.Log; -import android.widget.Button; -import android.widget.ProgressBar; - -import androidx.annotation.Nullable; - -import com.android.internal.content.PackageHelper; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -/** - * Send package to the package manager and handle results from package manager. Once the - * installation succeeds, start {@link InstallSuccess} or {@link InstallFailed}. - *

This has two phases: First send the data to the package manager, then wait until the package - * manager processed the result.

- */ -public class InstallInstalling extends Activity { - private static final String LOG_TAG = InstallInstalling.class.getSimpleName(); - - private static final String SESSION_ID = "com.android.packageinstaller.SESSION_ID"; - private static final String INSTALL_ID = "com.android.packageinstaller.INSTALL_ID"; - - private static final String BROADCAST_ACTION = - "com.android.packageinstaller.ACTION_INSTALL_COMMIT"; - - /** Listens to changed to the session and updates progress bar */ - private PackageInstaller.SessionCallback mSessionCallback; - - /** Task that sends the package to the package installer */ - private InstallingAsyncTask mInstallingTask; - - /** Id of the session to install the package */ - private int mSessionId; - - /** Id of the install event we wait for */ - private int mInstallId; - - /** URI of package to install */ - private Uri mPackageURI; - - /** The button that can cancel this dialog */ - private Button mCancelButton; - - @Override - protected void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - setContentView(R.layout.install_installing); - - ApplicationInfo appInfo = getIntent() - .getParcelableExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO); - mPackageURI = getIntent().getData(); - - if ("package".equals(mPackageURI.getScheme())) { - try { - getPackageManager().installExistingPackage(appInfo.packageName); - launchSuccess(); - } catch (PackageManager.NameNotFoundException e) { - launchFailure(PackageManager.INSTALL_FAILED_INTERNAL_ERROR, null); - } - } else { - final File sourceFile = new File(mPackageURI.getPath()); - PackageUtil.initSnippetForNewApp(this, PackageUtil.getAppSnippet(this, appInfo, - sourceFile), R.id.app_snippet); - - if (savedInstanceState != null) { - mSessionId = savedInstanceState.getInt(SESSION_ID); - mInstallId = savedInstanceState.getInt(INSTALL_ID); - - // Reregister for result; might instantly call back if result was delivered while - // activity was destroyed - try { - InstallEventReceiver.addObserver(this, mInstallId, - this::launchFinishBasedOnResult); - } catch (EventResultPersister.OutOfIdsException e) { - // Does not happen - } - } else { - PackageInstaller.SessionParams params = new PackageInstaller.SessionParams( - PackageInstaller.SessionParams.MODE_FULL_INSTALL); - params.installFlags = PackageManager.INSTALL_FULL_APP; - params.referrerUri = getIntent().getParcelableExtra(Intent.EXTRA_REFERRER); - params.originatingUri = getIntent() - .getParcelableExtra(Intent.EXTRA_ORIGINATING_URI); - params.originatingUid = getIntent().getIntExtra(Intent.EXTRA_ORIGINATING_UID, - UID_UNKNOWN); - params.installerPackageName = - getIntent().getStringExtra(Intent.EXTRA_INSTALLER_PACKAGE_NAME); - - File file = new File(mPackageURI.getPath()); - try { - PackageParser.PackageLite pkg = PackageParser.parsePackageLite(file, 0); - params.setAppPackageName(pkg.packageName); - params.setInstallLocation(pkg.installLocation); - params.setSize( - PackageHelper.calculateInstalledSize(pkg, false, params.abiOverride)); - } catch (PackageParser.PackageParserException e) { - Log.e(LOG_TAG, "Cannot parse package " + file + ". Assuming defaults."); - Log.e(LOG_TAG, - "Cannot calculate installed size " + file + ". Try only apk size."); - params.setSize(file.length()); - } catch (IOException e) { - Log.e(LOG_TAG, - "Cannot calculate installed size " + file + ". Try only apk size."); - params.setSize(file.length()); - } - - try { - mInstallId = InstallEventReceiver - .addObserver(this, EventResultPersister.GENERATE_NEW_ID, - this::launchFinishBasedOnResult); - } catch (EventResultPersister.OutOfIdsException e) { - launchFailure(PackageManager.INSTALL_FAILED_INTERNAL_ERROR, null); - } - - try { - mSessionId = getPackageManager().getPackageInstaller().createSession(params); - } catch (IOException e) { - launchFailure(PackageManager.INSTALL_FAILED_INTERNAL_ERROR, null); - } - } - - mCancelButton = (Button) findViewById(R.id.cancel_button); - - mCancelButton.setOnClickListener(view -> { - if (mInstallingTask != null) { - mInstallingTask.cancel(true); - } - - if (mSessionId > 0) { - getPackageManager().getPackageInstaller().abandonSession(mSessionId); - mSessionId = 0; - } - - setResult(RESULT_CANCELED); - finish(); - }); - - mSessionCallback = new InstallSessionCallback(); - } - } - - /** - * Launch the "success" version of the final package installer dialog - */ - private void launchSuccess() { - Intent successIntent = new Intent(getIntent()); - successIntent.setClass(this, InstallSuccess.class); - successIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT); - - startActivity(successIntent); - finish(); - } - - /** - * Launch the "failure" version of the final package installer dialog - * - * @param legacyStatus The status as used internally in the package manager. - * @param statusMessage The status description. - */ - private void launchFailure(int legacyStatus, String statusMessage) { - Intent failureIntent = new Intent(getIntent()); - failureIntent.setClass(this, InstallFailed.class); - failureIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT); - failureIntent.putExtra(PackageInstaller.EXTRA_LEGACY_STATUS, legacyStatus); - failureIntent.putExtra(PackageInstaller.EXTRA_STATUS_MESSAGE, statusMessage); - - startActivity(failureIntent); - finish(); - } - - @Override - protected void onStart() { - super.onStart(); - - getPackageManager().getPackageInstaller().registerSessionCallback(mSessionCallback); - } - - @Override - protected void onResume() { - super.onResume(); - - // This is the first onResume in a single life of the activity - if (mInstallingTask == null) { - PackageInstaller installer = getPackageManager().getPackageInstaller(); - PackageInstaller.SessionInfo sessionInfo = installer.getSessionInfo(mSessionId); - - if (sessionInfo != null && !sessionInfo.isActive()) { - mInstallingTask = new InstallingAsyncTask(); - mInstallingTask.execute(); - } else { - // we will receive a broadcast when the install is finished - mCancelButton.setEnabled(false); - setFinishOnTouchOutside(false); - } - } - } - - @Override - protected void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - - outState.putInt(SESSION_ID, mSessionId); - outState.putInt(INSTALL_ID, mInstallId); - } - - @Override - public void onBackPressed() { - if (mCancelButton.isEnabled()) { - super.onBackPressed(); - } - } - - @Override - protected void onStop() { - super.onStop(); - - getPackageManager().getPackageInstaller().unregisterSessionCallback(mSessionCallback); - } - - @Override - protected void onDestroy() { - if (mInstallingTask != null) { - mInstallingTask.cancel(true); - synchronized (mInstallingTask) { - while (!mInstallingTask.isDone) { - try { - mInstallingTask.wait(); - } catch (InterruptedException e) { - Log.i(LOG_TAG, "Interrupted while waiting for installing task to cancel", - e); - } - } - } - } - - InstallEventReceiver.removeObserver(this, mInstallId); - - super.onDestroy(); - } - - /** - * Launch the appropriate finish activity (success or failed) for the installation result. - * - * @param statusCode The installation result. - * @param legacyStatus The installation as used internally in the package manager. - * @param statusMessage The detailed installation result. - */ - private void launchFinishBasedOnResult(int statusCode, int legacyStatus, String statusMessage) { - if (statusCode == PackageInstaller.STATUS_SUCCESS) { - launchSuccess(); - } else { - launchFailure(legacyStatus, statusMessage); - } - } - - - private class InstallSessionCallback extends PackageInstaller.SessionCallback { - @Override - public void onCreated(int sessionId) { - // empty - } - - @Override - public void onBadgingChanged(int sessionId) { - // empty - } - - @Override - public void onActiveChanged(int sessionId, boolean active) { - // empty - } - - @Override - public void onProgressChanged(int sessionId, float progress) { - if (sessionId == mSessionId) { - ProgressBar progressBar = (ProgressBar)findViewById(R.id.progress_bar); - progressBar.setMax(Integer.MAX_VALUE); - progressBar.setProgress((int) (Integer.MAX_VALUE * progress)); - } - } - - @Override - public void onFinished(int sessionId, boolean success) { - // empty, finish is handled by InstallResultReceiver - } - } - - /** - * Send the package to the package installer and then register a event result observer that - * will call {@link #launchFinishBasedOnResult(int, int, String)} - */ - private final class InstallingAsyncTask extends AsyncTask { - volatile boolean isDone; - - @Override - protected PackageInstaller.Session doInBackground(Void... params) { - PackageInstaller.Session session; - try { - session = getPackageManager().getPackageInstaller().openSession(mSessionId); - } catch (IOException e) { - return null; - } - - session.setStagingProgress(0); - - try { - File file = new File(mPackageURI.getPath()); - - try (InputStream in = new FileInputStream(file)) { - long sizeBytes = file.length(); - try (OutputStream out = session - .openWrite("PackageInstaller", 0, sizeBytes)) { - byte[] buffer = new byte[1024 * 1024]; - while (true) { - int numRead = in.read(buffer); - - if (numRead == -1) { - session.fsync(out); - break; - } - - if (isCancelled()) { - session.close(); - break; - } - - out.write(buffer, 0, numRead); - if (sizeBytes > 0) { - float fraction = ((float) numRead / (float) sizeBytes); - session.addProgress(fraction); - } - } - } - } - - return session; - } catch (IOException | SecurityException e) { - Log.e(LOG_TAG, "Could not write package", e); - - session.close(); - - return null; - } finally { - synchronized (this) { - isDone = true; - notifyAll(); - } - } - } - - @Override - protected void onPostExecute(PackageInstaller.Session session) { - if (session != null) { - Intent broadcastIntent = new Intent(BROADCAST_ACTION); - broadcastIntent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND); - broadcastIntent.setPackage(getPackageName()); - broadcastIntent.putExtra(EventResultPersister.EXTRA_ID, mInstallId); - - PendingIntent pendingIntent = PendingIntent.getBroadcast( - InstallInstalling.this, - mInstallId, - broadcastIntent, - PendingIntent.FLAG_UPDATE_CURRENT); - - session.commit(pendingIntent.getIntentSender()); - mCancelButton.setEnabled(false); - setFinishOnTouchOutside(false); - } else { - getPackageManager().getPackageInstaller().abandonSession(mSessionId); - - if (!isCancelled()) { - launchFailure(PackageManager.INSTALL_FAILED_INVALID_APK, null); - } - } - } - } -} diff --git a/src/com/android/packageinstaller/InstallStaging.java b/src/com/android/packageinstaller/InstallStaging.java deleted file mode 100644 index bf72b65d8..000000000 --- a/src/com/android/packageinstaller/InstallStaging.java +++ /dev/null @@ -1,213 +0,0 @@ -/* - * 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. - */ - -package com.android.packageinstaller; - -import android.app.Activity; -import android.app.AlertDialog; -import android.app.Dialog; -import android.app.DialogFragment; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.net.Uri; -import android.os.AsyncTask; -import android.os.Bundle; -import androidx.annotation.Nullable; -import android.util.Log; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -/** - * If a package gets installed from an content URI this step loads the package and turns it into - * and installation from a file. Then it re-starts the installation as usual. - */ -public class InstallStaging extends Activity { - private static final String LOG_TAG = InstallStaging.class.getSimpleName(); - - private static final String STAGED_FILE = "STAGED_FILE"; - - /** Currently running task that loads the file from the content URI into a file */ - private @Nullable StagingAsyncTask mStagingTask; - - /** The file the package is in */ - private @Nullable File mStagedFile; - - @Override - protected void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - setContentView(R.layout.install_staging); - - if (savedInstanceState != null) { - mStagedFile = new File(savedInstanceState.getString(STAGED_FILE)); - - if (!mStagedFile.exists()) { - mStagedFile = null; - } - } - - findViewById(R.id.cancel_button).setOnClickListener(view -> { - if (mStagingTask != null) { - mStagingTask.cancel(true); - } - setResult(RESULT_CANCELED); - finish(); - }); - } - - @Override - protected void onResume() { - super.onResume(); - - // This is the first onResume in a single life of the activity - if (mStagingTask == null) { - // File does not exist, or became invalid - if (mStagedFile == null) { - // Create file delayed to be able to show error - try { - mStagedFile = TemporaryFileManager.getStagedFile(this); - } catch (IOException e) { - showError(); - return; - } - } - - mStagingTask = new StagingAsyncTask(); - mStagingTask.execute(getIntent().getData()); - } - } - - @Override - protected void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - - outState.putString(STAGED_FILE, mStagedFile.getPath()); - } - - @Override - protected void onDestroy() { - if (mStagingTask != null) { - mStagingTask.cancel(true); - } - - super.onDestroy(); - } - - /** - * Show an error message and set result as error. - */ - private void showError() { - (new ErrorDialog()).showAllowingStateLoss(getFragmentManager(), "error"); - - Intent result = new Intent(); - result.putExtra(Intent.EXTRA_INSTALL_RESULT, - PackageManager.INSTALL_FAILED_INVALID_APK); - setResult(RESULT_FIRST_USER, result); - } - - /** - * Dialog for errors while staging. - */ - public static class ErrorDialog extends DialogFragment { - private Activity mActivity; - - @Override - public void onAttach(Context context) { - super.onAttach(context); - - mActivity = (Activity) context; - } - - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - AlertDialog alertDialog = new AlertDialog.Builder(mActivity) - .setMessage(R.string.Parse_error_dlg_text) - .setPositiveButton(R.string.ok, - (dialog, which) -> mActivity.finish()) - .create(); - alertDialog.setCanceledOnTouchOutside(false); - - return alertDialog; - } - - @Override - public void onCancel(DialogInterface dialog) { - super.onCancel(dialog); - - mActivity.finish(); - } - } - - private final class StagingAsyncTask extends AsyncTask { - @Override - protected Boolean doInBackground(Uri... params) { - if (params == null || params.length <= 0) { - return false; - } - Uri packageUri = params[0]; - try (InputStream in = getContentResolver().openInputStream(packageUri)) { - // Despite the comments in ContentResolver#openInputStream the returned stream can - // be null. - if (in == null) { - return false; - } - - try (OutputStream out = new FileOutputStream(mStagedFile)) { - byte[] buffer = new byte[1024 * 1024]; - int bytesRead; - while ((bytesRead = in.read(buffer)) >= 0) { - // Be nice and respond to a cancellation - if (isCancelled()) { - return false; - } - out.write(buffer, 0, bytesRead); - } - } - } catch (IOException | SecurityException | IllegalStateException e) { - Log.w(LOG_TAG, "Error staging apk from content URI", e); - return false; - } - return true; - } - - @Override - protected void onPostExecute(Boolean success) { - if (success) { - // Now start the installation again from a file - Intent installIntent = new Intent(getIntent()); - installIntent.setClass(InstallStaging.this, DeleteStagedFileOnResult.class); - installIntent.setData(Uri.fromFile(mStagedFile)); - - if (installIntent.getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false)) { - installIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT); - } - - installIntent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); - startActivity(installIntent); - - InstallStaging.this.finish(); - } else { - showError(); - } - } - } -} diff --git a/src/com/android/packageinstaller/InstallStart.java b/src/com/android/packageinstaller/InstallStart.java deleted file mode 100644 index 96c6c2f62..000000000 --- a/src/com/android/packageinstaller/InstallStart.java +++ /dev/null @@ -1,218 +0,0 @@ -/* - * 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. - */ - -package com.android.packageinstaller; - -import static com.android.packageinstaller.PackageUtil.getMaxTargetSdkVersionForUid; - -import android.Manifest; -import android.app.Activity; -import android.app.ActivityManager; -import android.app.AppGlobals; -import android.content.ContentResolver; -import android.content.Intent; -import android.content.pm.ApplicationInfo; -import android.content.pm.IPackageManager; -import android.content.pm.PackageInstaller; -import android.content.pm.PackageManager; -import android.content.pm.ProviderInfo; -import android.net.Uri; -import android.os.Build; -import android.os.Bundle; -import android.os.RemoteException; -import android.util.Log; - -import androidx.annotation.Nullable; - -/** - * Select which activity is the first visible activity of the installation and forward the intent to - * it. - */ -public class InstallStart extends Activity { - private static final String LOG_TAG = InstallStart.class.getSimpleName(); - - private static final String DOWNLOADS_AUTHORITY = "downloads"; - private IPackageManager mIPackageManager; - private boolean mAbortInstall = false; - - @Override - protected void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - mIPackageManager = AppGlobals.getPackageManager(); - Intent intent = getIntent(); - String callingPackage = getCallingPackage(); - - // If the activity was started via a PackageInstaller session, we retrieve the calling - // package from that session - int sessionId = intent.getIntExtra(PackageInstaller.EXTRA_SESSION_ID, -1); - if (callingPackage == null && sessionId != -1) { - PackageInstaller packageInstaller = getPackageManager().getPackageInstaller(); - PackageInstaller.SessionInfo sessionInfo = packageInstaller.getSessionInfo(sessionId); - callingPackage = (sessionInfo != null) ? sessionInfo.getInstallerPackageName() : null; - } - - final ApplicationInfo sourceInfo = getSourceInfo(callingPackage); - final int originatingUid = getOriginatingUid(sourceInfo); - boolean isTrustedSource = false; - if (sourceInfo != null - && (sourceInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) { - isTrustedSource = intent.getBooleanExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, false); - } - - if (!isTrustedSource && originatingUid != PackageInstaller.SessionParams.UID_UNKNOWN) { - final int targetSdkVersion = getMaxTargetSdkVersionForUid(this, originatingUid); - if (targetSdkVersion < 0) { - Log.w(LOG_TAG, "Cannot get target sdk version for uid " + originatingUid); - // Invalid originating uid supplied. Abort install. - mAbortInstall = true; - } else if (targetSdkVersion >= Build.VERSION_CODES.O && !declaresAppOpPermission( - originatingUid, Manifest.permission.REQUEST_INSTALL_PACKAGES)) { - Log.e(LOG_TAG, "Requesting uid " + originatingUid + " needs to declare permission " - + Manifest.permission.REQUEST_INSTALL_PACKAGES); - mAbortInstall = true; - } - } - if (mAbortInstall) { - setResult(RESULT_CANCELED); - finish(); - return; - } - - Intent nextActivity = new Intent(intent); - nextActivity.setFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT); - - // The the installation source as the nextActivity thinks this activity is the source, hence - // set the originating UID and sourceInfo explicitly - nextActivity.putExtra(PackageInstallerActivity.EXTRA_CALLING_PACKAGE, callingPackage); - nextActivity.putExtra(PackageInstallerActivity.EXTRA_ORIGINAL_SOURCE_INFO, sourceInfo); - nextActivity.putExtra(Intent.EXTRA_ORIGINATING_UID, originatingUid); - - if (PackageInstaller.ACTION_CONFIRM_INSTALL.equals(intent.getAction())) { - nextActivity.setClass(this, PackageInstallerActivity.class); - } else { - Uri packageUri = intent.getData(); - - if (packageUri != null && (packageUri.getScheme().equals(ContentResolver.SCHEME_FILE) - || packageUri.getScheme().equals(ContentResolver.SCHEME_CONTENT))) { - // Copy file to prevent it from being changed underneath this process - nextActivity.setClass(this, InstallStaging.class); - } else if (packageUri != null && packageUri.getScheme().equals( - PackageInstallerActivity.SCHEME_PACKAGE)) { - nextActivity.setClass(this, PackageInstallerActivity.class); - } else { - Intent result = new Intent(); - result.putExtra(Intent.EXTRA_INSTALL_RESULT, - PackageManager.INSTALL_FAILED_INVALID_URI); - setResult(RESULT_FIRST_USER, result); - - nextActivity = null; - } - } - - if (nextActivity != null) { - startActivity(nextActivity); - } - finish(); - } - - private boolean declaresAppOpPermission(int uid, String permission) { - try { - final String[] packages = mIPackageManager.getAppOpPermissionPackages(permission); - if (packages == null) { - return false; - } - for (String packageName : packages) { - try { - if (uid == getPackageManager().getPackageUid(packageName, 0)) { - return true; - } - } catch (PackageManager.NameNotFoundException e) { - // Ignore and try the next package - } - } - } catch (RemoteException rexc) { - // If remote package manager cannot be reached, install will likely fail anyway. - } - return false; - } - - /** - * @return the ApplicationInfo for the installation source (the calling package), if available - */ - private ApplicationInfo getSourceInfo(@Nullable String callingPackage) { - if (callingPackage != null) { - try { - return getPackageManager().getApplicationInfo(callingPackage, 0); - } catch (PackageManager.NameNotFoundException ex) { - // ignore - } - } - return null; - } - - /** - * Get the originating uid if possible, or - * {@link android.content.pm.PackageInstaller.SessionParams#UID_UNKNOWN} if not available - * - * @param sourceInfo The source of this installation - * @return The UID of the installation source or UID_UNKNOWN - */ - private int getOriginatingUid(@Nullable ApplicationInfo sourceInfo) { - // The originating uid from the intent. We only trust/use this if it comes from either - // the document manager app or the downloads provider - final int uidFromIntent = getIntent().getIntExtra(Intent.EXTRA_ORIGINATING_UID, - PackageInstaller.SessionParams.UID_UNKNOWN); - - final int callingUid; - if (sourceInfo != null) { - callingUid = sourceInfo.uid; - } else { - try { - callingUid = ActivityManager.getService() - .getLaunchedFromUid(getActivityToken()); - } catch (RemoteException ex) { - // Cannot reach ActivityManager. Aborting install. - Log.e(LOG_TAG, "Could not determine the launching uid."); - mAbortInstall = true; - return PackageInstaller.SessionParams.UID_UNKNOWN; - } - } - try { - if (mIPackageManager.checkUidPermission(Manifest.permission.MANAGE_DOCUMENTS, - callingUid) == PackageManager.PERMISSION_GRANTED) { - return uidFromIntent; - } - } catch (RemoteException rexc) { - // Ignore. Should not happen. - } - if (isSystemDownloadsProvider(callingUid)) { - return uidFromIntent; - } - // We don't trust uid from the intent. Use the calling uid instead. - return callingUid; - } - - private boolean isSystemDownloadsProvider(int uid) { - final ProviderInfo downloadProviderPackage = getPackageManager().resolveContentProvider( - DOWNLOADS_AUTHORITY, 0); - if (downloadProviderPackage == null) { - // There seems to be no currently enabled downloads provider on the system. - return false; - } - final ApplicationInfo appInfo = downloadProviderPackage.applicationInfo; - return (appInfo.isSystemApp() && uid == appInfo.uid); - } -} diff --git a/src/com/android/packageinstaller/InstallSuccess.java b/src/com/android/packageinstaller/InstallSuccess.java deleted file mode 100644 index ae902d3af..000000000 --- a/src/com/android/packageinstaller/InstallSuccess.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * 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. - */ - -package com.android.packageinstaller; - -import android.app.Activity; -import android.content.ActivityNotFoundException; -import android.content.Intent; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.net.Uri; -import android.os.Bundle; -import androidx.annotation.Nullable; -import android.util.Log; -import android.widget.Button; - -import java.io.File; -import java.util.List; - -/** - * Finish installation: Return status code to the caller or display "success" UI to user - */ -public class InstallSuccess extends Activity { - private static final String LOG_TAG = InstallSuccess.class.getSimpleName(); - - @Override - protected void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - if (getIntent().getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false)) { - // Return result if requested - Intent result = new Intent(); - result.putExtra(Intent.EXTRA_INSTALL_RESULT, PackageManager.INSTALL_SUCCEEDED); - setResult(Activity.RESULT_OK, result); - finish(); - } else { - Intent intent = getIntent(); - ApplicationInfo appInfo = - intent.getParcelableExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO); - Uri packageURI = intent.getData(); - - setContentView(R.layout.install_success); - - // Set header icon and title - PackageUtil.AppSnippet as; - PackageManager pm = getPackageManager(); - - if ("package".equals(packageURI.getScheme())) { - as = new PackageUtil.AppSnippet(pm.getApplicationLabel(appInfo), - pm.getApplicationIcon(appInfo)); - } else { - File sourceFile = new File(packageURI.getPath()); - as = PackageUtil.getAppSnippet(this, appInfo, sourceFile); - } - - PackageUtil.initSnippetForNewApp(this, as, R.id.app_snippet); - - // Set up "done" button - findViewById(R.id.done_button).setOnClickListener(view -> { - if (appInfo.packageName != null) { - Log.i(LOG_TAG, "Finished installing " + appInfo.packageName); - } - finish(); - }); - - // Enable or disable "launch" button - Intent launchIntent = getPackageManager().getLaunchIntentForPackage( - appInfo.packageName); - boolean enabled = false; - if (launchIntent != null) { - List list = getPackageManager().queryIntentActivities(launchIntent, - 0); - if (list != null && list.size() > 0) { - enabled = true; - } - } - - Button launchButton = (Button)findViewById(R.id.launch_button); - if (enabled) { - launchButton.setOnClickListener(view -> { - try { - startActivity(launchIntent); - } catch (ActivityNotFoundException | SecurityException e) { - Log.e(LOG_TAG, "Could not start activity", e); - } - finish(); - }); - } else { - launchButton.setEnabled(false); - } - } - } -} diff --git a/src/com/android/packageinstaller/PackageInstallerActivity.java b/src/com/android/packageinstaller/PackageInstallerActivity.java deleted file mode 100644 index 83c91eaad..000000000 --- a/src/com/android/packageinstaller/PackageInstallerActivity.java +++ /dev/null @@ -1,770 +0,0 @@ -/* -** -** Copyright 2007, 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.packageinstaller; - -import android.Manifest; -import android.app.AlertDialog; -import android.app.AppGlobals; -import android.app.AppOpsManager; -import android.app.Dialog; -import android.app.DialogFragment; -import android.content.ActivityNotFoundException; -import android.content.ContentResolver; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.pm.ApplicationInfo; -import android.content.pm.IPackageManager; -import android.content.pm.PackageInfo; -import android.content.pm.PackageInstaller; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; -import android.content.pm.PackageParser; -import android.content.pm.PackageUserState; -import android.net.Uri; -import android.os.Bundle; -import android.os.Process; -import android.os.RemoteException; -import android.os.UserManager; -import android.provider.Settings; -import android.util.Log; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.Button; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.annotation.StringRes; - -import com.android.packageinstaller.permission.ui.OverlayTouchActivity; - -import java.io.File; - -/** - * This activity is launched when a new application is installed via side loading - * The package is first parsed and the user is notified of parse errors via a dialog. - * If the package is successfully parsed, the user is notified to turn on the install unknown - * applications setting. A memory check is made at this point and the user is notified of out - * of memory conditions if any. If the package is already existing on the device, - * a confirmation dialog (to replace the existing package) is presented to the user. - * Based on the user response the package is then installed by launching InstallAppConfirm - * sub activity. All state transitions are handled in this activity - */ -public class PackageInstallerActivity extends OverlayTouchActivity implements OnClickListener { - private static final String TAG = "PackageInstaller"; - - private static final int REQUEST_TRUST_EXTERNAL_SOURCE = 1; - - static final String SCHEME_PACKAGE = "package"; - - static final String EXTRA_CALLING_PACKAGE = "EXTRA_CALLING_PACKAGE"; - static final String EXTRA_ORIGINAL_SOURCE_INFO = "EXTRA_ORIGINAL_SOURCE_INFO"; - private static final String ALLOW_UNKNOWN_SOURCES_KEY = - PackageInstallerActivity.class.getName() + "ALLOW_UNKNOWN_SOURCES_KEY"; - - private int mSessionId = -1; - private Uri mPackageURI; - private Uri mOriginatingURI; - private Uri mReferrerURI; - private int mOriginatingUid = PackageInstaller.SessionParams.UID_UNKNOWN; - private String mOriginatingPackage; // The package name corresponding to #mOriginatingUid - - private boolean localLOGV = false; - PackageManager mPm; - IPackageManager mIpm; - AppOpsManager mAppOpsManager; - UserManager mUserManager; - PackageInstaller mInstaller; - PackageInfo mPkgInfo; - String mCallingPackage; - ApplicationInfo mSourceInfo; - - // ApplicationInfo object primarily used for already existing applications - private ApplicationInfo mAppInfo = null; - - // Buttons to indicate user acceptance - private Button mOk; - private Button mCancel; - - private PackageUtil.AppSnippet mAppSnippet; - - static final String PREFS_ALLOWED_SOURCES = "allowed_sources"; - - // Dialog identifiers used in showDialog - private static final int DLG_BASE = 0; - private static final int DLG_PACKAGE_ERROR = DLG_BASE + 2; - private static final int DLG_OUT_OF_SPACE = DLG_BASE + 3; - private static final int DLG_INSTALL_ERROR = DLG_BASE + 4; - private static final int DLG_UNKNOWN_SOURCES_RESTRICTED_FOR_USER = DLG_BASE + 5; - private static final int DLG_ANONYMOUS_SOURCE = DLG_BASE + 6; - private static final int DLG_NOT_SUPPORTED_ON_WEAR = DLG_BASE + 7; - private static final int DLG_EXTERNAL_SOURCE_BLOCKED = DLG_BASE + 8; - private static final int DLG_INSTALL_APPS_RESTRICTED_FOR_USER = DLG_BASE + 9; - - // If unknown sources are temporary allowed - private boolean mAllowUnknownSources; - - // Would the mOk button be enabled if this activity would be resumed - private boolean mEnableOk = false; - - private void startInstallConfirm() { - int msg; - - if (mAppInfo != null) { - msg = (mAppInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0 - ? R.string.install_confirm_question_update_system - : R.string.install_confirm_question_update; - } else { - // This is a new application with no permissions. - msg = R.string.install_confirm_question; - } - - ((TextView) findViewById(R.id.install_confirm_question)).setText(msg); - - mEnableOk = true; - mOk.setEnabled(true); - } - - /** - * Replace any dialog shown by the dialog with the one for the given {@link #createDialog id}. - * - * @param id The dialog type to add - */ - private void showDialogInner(int id) { - DialogFragment currentDialog = - (DialogFragment) getFragmentManager().findFragmentByTag("dialog"); - if (currentDialog != null) { - currentDialog.dismissAllowingStateLoss(); - } - - DialogFragment newDialog = createDialog(id); - if (newDialog != null) { - newDialog.showAllowingStateLoss(getFragmentManager(), "dialog"); - } - } - - /** - * Create a new dialog. - * - * @param id The id of the dialog (determines dialog type) - * - * @return The dialog - */ - private DialogFragment createDialog(int id) { - switch (id) { - case DLG_PACKAGE_ERROR: - return SimpleErrorDialog.newInstance(R.string.Parse_error_dlg_text); - case DLG_OUT_OF_SPACE: - return OutOfSpaceDialog.newInstance( - mPm.getApplicationLabel(mPkgInfo.applicationInfo)); - case DLG_INSTALL_ERROR: - return InstallErrorDialog.newInstance( - mPm.getApplicationLabel(mPkgInfo.applicationInfo)); - case DLG_NOT_SUPPORTED_ON_WEAR: - return NotSupportedOnWearDialog.newInstance(); - case DLG_INSTALL_APPS_RESTRICTED_FOR_USER: - return SimpleErrorDialog.newInstance( - R.string.install_apps_user_restriction_dlg_text); - case DLG_UNKNOWN_SOURCES_RESTRICTED_FOR_USER: - return SimpleErrorDialog.newInstance( - R.string.unknown_apps_user_restriction_dlg_text); - case DLG_EXTERNAL_SOURCE_BLOCKED: - return ExternalSourcesBlockedDialog.newInstance(mOriginatingPackage); - case DLG_ANONYMOUS_SOURCE: - return AnonymousSourceDialog.newInstance(); - } - return null; - } - - @Override - public void onActivityResult(int request, int result, Intent data) { - if (request == REQUEST_TRUST_EXTERNAL_SOURCE && result == RESULT_OK) { - // The user has just allowed this package to install other packages (via Settings). - mAllowUnknownSources = true; - - // Log the fact that the app is requesting an install, and is now allowed to do it - // (before this point we could only log that it's requesting an install, but isn't - // allowed to do it yet). - int appOpCode = - AppOpsManager.permissionToOpCode(Manifest.permission.REQUEST_INSTALL_PACKAGES); - mAppOpsManager.noteOpNoThrow(appOpCode, mOriginatingUid, mOriginatingPackage); - - DialogFragment currentDialog = - (DialogFragment) getFragmentManager().findFragmentByTag("dialog"); - if (currentDialog != null) { - currentDialog.dismissAllowingStateLoss(); - } - - initiateInstall(); - } else { - finish(); - } - } - - private String getPackageNameForUid(int sourceUid) { - String[] packagesForUid = mPm.getPackagesForUid(sourceUid); - if (packagesForUid == null) { - return null; - } - if (packagesForUid.length > 1) { - if (mCallingPackage != null) { - for (String packageName : packagesForUid) { - if (packageName.equals(mCallingPackage)) { - return packageName; - } - } - } - Log.i(TAG, "Multiple packages found for source uid " + sourceUid); - } - return packagesForUid[0]; - } - - private boolean isInstallRequestFromUnknownSource(Intent intent) { - if (mCallingPackage != null && intent.getBooleanExtra( - Intent.EXTRA_NOT_UNKNOWN_SOURCE, false)) { - if (mSourceInfo != null) { - if ((mSourceInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) - != 0) { - // Privileged apps can bypass unknown sources check if they want. - return false; - } - } - } - return true; - } - - private void initiateInstall() { - String pkgName = mPkgInfo.packageName; - // Check if there is already a package on the device with this name - // but it has been renamed to something else. - String[] oldName = mPm.canonicalToCurrentPackageNames(new String[] { pkgName }); - if (oldName != null && oldName.length > 0 && oldName[0] != null) { - pkgName = oldName[0]; - mPkgInfo.packageName = pkgName; - mPkgInfo.applicationInfo.packageName = pkgName; - } - // Check if package is already installed. display confirmation dialog if replacing pkg - try { - // This is a little convoluted because we want to get all uninstalled - // apps, but this may include apps with just data, and if it is just - // data we still want to count it as "installed". - mAppInfo = mPm.getApplicationInfo(pkgName, - PackageManager.MATCH_UNINSTALLED_PACKAGES); - if ((mAppInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { - mAppInfo = null; - } - } catch (NameNotFoundException e) { - mAppInfo = null; - } - - startInstallConfirm(); - } - - void setPmResult(int pmResult) { - Intent result = new Intent(); - result.putExtra(Intent.EXTRA_INSTALL_RESULT, pmResult); - setResult(pmResult == PackageManager.INSTALL_SUCCEEDED - ? RESULT_OK : RESULT_FIRST_USER, result); - } - - @Override - protected void onCreate(Bundle icicle) { - super.onCreate(null); - - if (icicle != null) { - mAllowUnknownSources = icicle.getBoolean(ALLOW_UNKNOWN_SOURCES_KEY); - } - - mPm = getPackageManager(); - mIpm = AppGlobals.getPackageManager(); - mAppOpsManager = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE); - mInstaller = mPm.getPackageInstaller(); - mUserManager = (UserManager) getSystemService(Context.USER_SERVICE); - - final Intent intent = getIntent(); - - mCallingPackage = intent.getStringExtra(EXTRA_CALLING_PACKAGE); - mSourceInfo = intent.getParcelableExtra(EXTRA_ORIGINAL_SOURCE_INFO); - mOriginatingUid = intent.getIntExtra(Intent.EXTRA_ORIGINATING_UID, - PackageInstaller.SessionParams.UID_UNKNOWN); - mOriginatingPackage = (mOriginatingUid != PackageInstaller.SessionParams.UID_UNKNOWN) - ? getPackageNameForUid(mOriginatingUid) : null; - - - final Uri packageUri; - - if (PackageInstaller.ACTION_CONFIRM_INSTALL.equals(intent.getAction())) { - final int sessionId = intent.getIntExtra(PackageInstaller.EXTRA_SESSION_ID, -1); - final PackageInstaller.SessionInfo info = mInstaller.getSessionInfo(sessionId); - if (info == null || !info.sealed || info.resolvedBaseCodePath == null) { - Log.w(TAG, "Session " + mSessionId + " in funky state; ignoring"); - finish(); - return; - } - - mSessionId = sessionId; - packageUri = Uri.fromFile(new File(info.resolvedBaseCodePath)); - mOriginatingURI = null; - mReferrerURI = null; - } else { - mSessionId = -1; - packageUri = intent.getData(); - mOriginatingURI = intent.getParcelableExtra(Intent.EXTRA_ORIGINATING_URI); - mReferrerURI = intent.getParcelableExtra(Intent.EXTRA_REFERRER); - } - - // if there's nothing to do, quietly slip into the ether - if (packageUri == null) { - Log.w(TAG, "Unspecified source"); - setPmResult(PackageManager.INSTALL_FAILED_INVALID_URI); - finish(); - return; - } - - if (DeviceUtils.isWear(this)) { - showDialogInner(DLG_NOT_SUPPORTED_ON_WEAR); - return; - } - - boolean wasSetUp = processPackageUri(packageUri); - if (!wasSetUp) { - return; - } - - // load dummy layout with OK button disabled until we override this layout in - // startInstallConfirm - bindUi(R.layout.install_confirm); - checkIfAllowedAndInitiateInstall(); - } - - @Override - protected void onResume() { - super.onResume(); - - if (mOk != null) { - mOk.setEnabled(mEnableOk); - } - } - - @Override - protected void onPause() { - super.onPause(); - - if (mOk != null) { - // Don't allow the install button to be clicked as there might be overlays - mOk.setEnabled(false); - } - } - - @Override - protected void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - - outState.putBoolean(ALLOW_UNKNOWN_SOURCES_KEY, mAllowUnknownSources); - } - - private void bindUi(int layout) { - setContentView(layout); - - mOk = (Button) findViewById(R.id.ok_button); - mCancel = (Button)findViewById(R.id.cancel_button); - mOk.setOnClickListener(this); - mCancel.setOnClickListener(this); - - mOk.setEnabled(false); - - PackageUtil.initSnippetForNewApp(this, mAppSnippet, R.id.app_snippet); - } - - /** - * Check if it is allowed to install the package and initiate install if allowed. If not allowed - * show the appropriate dialog. - */ - private void checkIfAllowedAndInitiateInstall() { - // Check for install apps user restriction first. - final int installAppsRestrictionSource = mUserManager.getUserRestrictionSource( - UserManager.DISALLOW_INSTALL_APPS, Process.myUserHandle()); - if ((installAppsRestrictionSource & UserManager.RESTRICTION_SOURCE_SYSTEM) != 0) { - showDialogInner(DLG_INSTALL_APPS_RESTRICTED_FOR_USER); - return; - } else if (installAppsRestrictionSource != UserManager.RESTRICTION_NOT_SET) { - startActivity(new Intent(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS)); - finish(); - return; - } - - if (mAllowUnknownSources || !isInstallRequestFromUnknownSource(getIntent())) { - initiateInstall(); - } else { - // Check for unknown sources restriction - final int unknownSourcesRestrictionSource = mUserManager.getUserRestrictionSource( - UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, Process.myUserHandle()); - if ((unknownSourcesRestrictionSource & UserManager.RESTRICTION_SOURCE_SYSTEM) != 0) { - showDialogInner(DLG_UNKNOWN_SOURCES_RESTRICTED_FOR_USER); - } else if (unknownSourcesRestrictionSource != UserManager.RESTRICTION_NOT_SET) { - startActivity(new Intent(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS)); - finish(); - } else { - handleUnknownSources(); - } - } - } - - private void handleUnknownSources() { - if (mOriginatingPackage == null) { - Log.i(TAG, "No source found for package " + mPkgInfo.packageName); - showDialogInner(DLG_ANONYMOUS_SOURCE); - return; - } - // Shouldn't use static constant directly, see b/65534401. - final int appOpCode = - AppOpsManager.permissionToOpCode(Manifest.permission.REQUEST_INSTALL_PACKAGES); - final int appOpMode = mAppOpsManager.noteOpNoThrow(appOpCode, - mOriginatingUid, mOriginatingPackage); - switch (appOpMode) { - case AppOpsManager.MODE_DEFAULT: - try { - int result = mIpm.checkUidPermission( - Manifest.permission.REQUEST_INSTALL_PACKAGES, mOriginatingUid); - if (result == PackageManager.PERMISSION_GRANTED) { - initiateInstall(); - break; - } - } catch (RemoteException exc) { - Log.e(TAG, "Unable to talk to package manager"); - } - mAppOpsManager.setMode(appOpCode, mOriginatingUid, - mOriginatingPackage, AppOpsManager.MODE_ERRORED); - // fall through - case AppOpsManager.MODE_ERRORED: - showDialogInner(DLG_EXTERNAL_SOURCE_BLOCKED); - break; - case AppOpsManager.MODE_ALLOWED: - initiateInstall(); - break; - default: - Log.e(TAG, "Invalid app op mode " + appOpMode - + " for OP_REQUEST_INSTALL_PACKAGES found for uid " + mOriginatingUid); - finish(); - break; - } - } - - /** - * Parse the Uri and set up the installer for this package. - * - * @param packageUri The URI to parse - * - * @return {@code true} iff the installer could be set up - */ - private boolean processPackageUri(final Uri packageUri) { - mPackageURI = packageUri; - - final String scheme = packageUri.getScheme(); - - switch (scheme) { - case SCHEME_PACKAGE: { - try { - mPkgInfo = mPm.getPackageInfo(packageUri.getSchemeSpecificPart(), - PackageManager.GET_PERMISSIONS - | PackageManager.MATCH_UNINSTALLED_PACKAGES); - } catch (NameNotFoundException e) { - } - if (mPkgInfo == null) { - Log.w(TAG, "Requested package " + packageUri.getScheme() - + " not available. Discontinuing installation"); - showDialogInner(DLG_PACKAGE_ERROR); - setPmResult(PackageManager.INSTALL_FAILED_INVALID_APK); - return false; - } - mAppSnippet = new PackageUtil.AppSnippet(mPm.getApplicationLabel(mPkgInfo.applicationInfo), - mPm.getApplicationIcon(mPkgInfo.applicationInfo)); - } break; - - case ContentResolver.SCHEME_FILE: { - File sourceFile = new File(packageUri.getPath()); - PackageParser.Package parsed = PackageUtil.getPackageInfo(this, sourceFile); - - // Check for parse errors - if (parsed == null) { - Log.w(TAG, "Parse error when parsing manifest. Discontinuing installation"); - showDialogInner(DLG_PACKAGE_ERROR); - setPmResult(PackageManager.INSTALL_FAILED_INVALID_APK); - return false; - } - mPkgInfo = PackageParser.generatePackageInfo(parsed, null, - PackageManager.GET_PERMISSIONS, 0, 0, null, - new PackageUserState()); - mAppSnippet = PackageUtil.getAppSnippet(this, mPkgInfo.applicationInfo, sourceFile); - } break; - - default: { - throw new IllegalArgumentException("Unexpected URI scheme " + packageUri); - } - } - - return true; - } - - @Override - public void onBackPressed() { - if (mSessionId != -1) { - mInstaller.setPermissionsResult(mSessionId, false); - } - super.onBackPressed(); - } - - public void onClick(View v) { - if (v == mOk) { - if (mOk.isEnabled()) { - if (mSessionId != -1) { - mInstaller.setPermissionsResult(mSessionId, true); - finish(); - } else { - startInstall(); - } - } - } else if (v == mCancel) { - // Cancel and finish - setResult(RESULT_CANCELED); - if (mSessionId != -1) { - mInstaller.setPermissionsResult(mSessionId, false); - } - finish(); - } - } - - private void startInstall() { - // Start subactivity to actually install the application - Intent newIntent = new Intent(); - newIntent.putExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO, - mPkgInfo.applicationInfo); - newIntent.setData(mPackageURI); - newIntent.setClass(this, InstallInstalling.class); - String installerPackageName = getIntent().getStringExtra( - Intent.EXTRA_INSTALLER_PACKAGE_NAME); - if (mOriginatingURI != null) { - newIntent.putExtra(Intent.EXTRA_ORIGINATING_URI, mOriginatingURI); - } - if (mReferrerURI != null) { - newIntent.putExtra(Intent.EXTRA_REFERRER, mReferrerURI); - } - if (mOriginatingUid != PackageInstaller.SessionParams.UID_UNKNOWN) { - newIntent.putExtra(Intent.EXTRA_ORIGINATING_UID, mOriginatingUid); - } - if (installerPackageName != null) { - newIntent.putExtra(Intent.EXTRA_INSTALLER_PACKAGE_NAME, - installerPackageName); - } - if (getIntent().getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false)) { - newIntent.putExtra(Intent.EXTRA_RETURN_RESULT, true); - } - newIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT); - if(localLOGV) Log.i(TAG, "downloaded app uri="+mPackageURI); - startActivity(newIntent); - finish(); - } - - /** - * A simple error dialog showing a message - */ - public static class SimpleErrorDialog extends DialogFragment { - private static final String MESSAGE_KEY = - SimpleErrorDialog.class.getName() + "MESSAGE_KEY"; - - static SimpleErrorDialog newInstance(@StringRes int message) { - SimpleErrorDialog dialog = new SimpleErrorDialog(); - - Bundle args = new Bundle(); - args.putInt(MESSAGE_KEY, message); - dialog.setArguments(args); - - return dialog; - } - - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - return new AlertDialog.Builder(getActivity()) - .setMessage(getArguments().getInt(MESSAGE_KEY)) - .setPositiveButton(R.string.ok, (dialog, which) -> getActivity().finish()) - .create(); - } - } - - /** - * Dialog to show when the source of apk can not be identified - */ - public static class AnonymousSourceDialog extends DialogFragment { - static AnonymousSourceDialog newInstance() { - return new AnonymousSourceDialog(); - } - - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - return new AlertDialog.Builder(getActivity()) - .setMessage(R.string.anonymous_source_warning) - .setPositiveButton(R.string.anonymous_source_continue, - ((dialog, which) -> { - PackageInstallerActivity activity = ((PackageInstallerActivity) - getActivity()); - - activity.mAllowUnknownSources = true; - activity.initiateInstall(); - })) - .setNegativeButton(R.string.cancel, ((dialog, which) -> getActivity().finish())) - .create(); - } - - @Override - public void onCancel(DialogInterface dialog) { - getActivity().finish(); - } - } - - /** - * An error dialog shown when the app is not supported on wear - */ - public static class NotSupportedOnWearDialog extends SimpleErrorDialog { - static SimpleErrorDialog newInstance() { - return SimpleErrorDialog.newInstance(R.string.wear_not_allowed_dlg_text); - } - - @Override - public void onCancel(DialogInterface dialog) { - getActivity().setResult(RESULT_OK); - getActivity().finish(); - } - } - - /** - * An error dialog shown when the device is out of space - */ - public static class OutOfSpaceDialog extends AppErrorDialog { - static AppErrorDialog newInstance(@NonNull CharSequence applicationLabel) { - OutOfSpaceDialog dialog = new OutOfSpaceDialog(); - dialog.setArgument(applicationLabel); - return dialog; - } - - @Override - protected Dialog createDialog(@NonNull CharSequence argument) { - String dlgText = getString(R.string.out_of_space_dlg_text, argument); - return new AlertDialog.Builder(getActivity()) - .setMessage(dlgText) - .setPositiveButton(R.string.manage_applications, (dialog, which) -> { - // launch manage applications - Intent intent = new Intent("android.intent.action.MANAGE_PACKAGE_STORAGE"); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - startActivity(intent); - getActivity().finish(); - }) - .setNegativeButton(R.string.cancel, (dialog, which) -> getActivity().finish()) - .create(); - } - } - - /** - * A generic install-error dialog - */ - public static class InstallErrorDialog extends AppErrorDialog { - static AppErrorDialog newInstance(@NonNull CharSequence applicationLabel) { - InstallErrorDialog dialog = new InstallErrorDialog(); - dialog.setArgument(applicationLabel); - return dialog; - } - - @Override - protected Dialog createDialog(@NonNull CharSequence argument) { - return new AlertDialog.Builder(getActivity()) - .setNeutralButton(R.string.ok, (dialog, which) -> getActivity().finish()) - .setMessage(getString(R.string.install_failed_msg, argument)) - .create(); - } - } - - /** - * An error dialog shown when external sources are not allowed - */ - public static class ExternalSourcesBlockedDialog extends AppErrorDialog { - static AppErrorDialog newInstance(@NonNull String originationPkg) { - ExternalSourcesBlockedDialog dialog = new ExternalSourcesBlockedDialog(); - dialog.setArgument(originationPkg); - return dialog; - } - - @Override - protected Dialog createDialog(@NonNull CharSequence argument) { - try { - PackageManager pm = getActivity().getPackageManager(); - - ApplicationInfo sourceInfo = pm.getApplicationInfo(argument.toString(), 0); - - return new AlertDialog.Builder(getActivity()) - .setTitle(pm.getApplicationLabel(sourceInfo)) - .setIcon(pm.getApplicationIcon(sourceInfo)) - .setMessage(R.string.untrusted_external_source_warning) - .setPositiveButton(R.string.external_sources_settings, - (dialog, which) -> { - Intent settingsIntent = new Intent(); - settingsIntent.setAction( - Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES); - final Uri packageUri = Uri.parse("package:" + argument); - settingsIntent.setData(packageUri); - try { - getActivity().startActivityForResult(settingsIntent, - REQUEST_TRUST_EXTERNAL_SOURCE); - } catch (ActivityNotFoundException exc) { - Log.e(TAG, "Settings activity not found for action: " - + Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES); - } - }) - .setNegativeButton(R.string.cancel, - (dialog, which) -> getActivity().finish()) - .create(); - } catch (NameNotFoundException e) { - Log.e(TAG, "Did not find app info for " + argument); - getActivity().finish(); - return null; - } - } - } - - /** - * Superclass for all error dialogs. Stores a single CharSequence argument - */ - public abstract static class AppErrorDialog extends DialogFragment { - private static final String ARGUMENT_KEY = AppErrorDialog.class.getName() + "ARGUMENT_KEY"; - - protected void setArgument(@NonNull CharSequence argument) { - Bundle args = new Bundle(); - args.putCharSequence(ARGUMENT_KEY, argument); - setArguments(args); - } - - protected abstract Dialog createDialog(@NonNull CharSequence argument); - - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - return createDialog(getArguments().getString(ARGUMENT_KEY)); - } - - @Override - public void onCancel(DialogInterface dialog) { - getActivity().finish(); - } - } -} diff --git a/src/com/android/packageinstaller/PackageUtil.java b/src/com/android/packageinstaller/PackageUtil.java deleted file mode 100644 index 68daed760..000000000 --- a/src/com/android/packageinstaller/PackageUtil.java +++ /dev/null @@ -1,210 +0,0 @@ -/* -** -** Copyright 2007, 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.packageinstaller; - -import android.app.Activity; -import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageParser; -import android.content.pm.PackageParser.PackageParserException; -import android.content.res.AssetManager; -import android.content.res.Resources; -import android.graphics.drawable.Drawable; -import android.os.UserHandle; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import android.util.Log; -import android.view.View; -import android.widget.ImageView; -import android.widget.TextView; - -import java.io.File; - -/** - * This is a utility class for defining some utility methods and constants - * used in the package installer application. - */ -public class PackageUtil { - private static final String LOG_TAG = PackageUtil.class.getSimpleName(); - - public static final String PREFIX="com.android.packageinstaller."; - public static final String INTENT_ATTR_INSTALL_STATUS = PREFIX+"installStatus"; - public static final String INTENT_ATTR_APPLICATION_INFO=PREFIX+"applicationInfo"; - public static final String INTENT_ATTR_PERMISSIONS_LIST=PREFIX+"PermissionsList"; - //intent attribute strings related to uninstall - public static final String INTENT_ATTR_PACKAGE_NAME=PREFIX+"PackageName"; - - /** - * Utility method to get package information for a given {@link File} - */ - public static PackageParser.Package getPackageInfo(Context context, File sourceFile) { - final PackageParser parser = new PackageParser(); - parser.setCallback(new PackageParser.CallbackImpl(context.getPackageManager())); - try { - return parser.parsePackage(sourceFile, 0); - } catch (PackageParserException e) { - return null; - } - } - - public static View initSnippet(View snippetView, CharSequence label, Drawable icon) { - ((ImageView)snippetView.findViewById(R.id.app_icon)).setImageDrawable(icon); - ((TextView)snippetView.findViewById(R.id.app_name)).setText(label); - return snippetView; - } - - /** - * Utility method to display a snippet of an installed application. - * The content view should have been set on context before invoking this method. - * appSnippet view should include R.id.app_icon and R.id.app_name - * defined on it. - * - * @param pContext context of package that can load the resources - * @param componentInfo ComponentInfo object whose resources are to be loaded - * @param snippetView the snippet view - */ - public static View initSnippetForInstalledApp(Context pContext, - ApplicationInfo appInfo, View snippetView) { - return initSnippetForInstalledApp(pContext, appInfo, snippetView, null); - } - - /** - * Utility method to display a snippet of an installed application. - * The content view should have been set on context before invoking this method. - * appSnippet view should include R.id.app_icon and R.id.app_name - * defined on it. - * - * @param pContext context of package that can load the resources - * @param componentInfo ComponentInfo object whose resources are to be loaded - * @param snippetView the snippet view - * @param UserHandle user that the app si installed for. - */ - public static View initSnippetForInstalledApp(Context pContext, - ApplicationInfo appInfo, View snippetView, UserHandle user) { - final PackageManager pm = pContext.getPackageManager(); - Drawable icon = appInfo.loadIcon(pm); - if (user != null) { - icon = pContext.getPackageManager().getUserBadgedIcon(icon, user); - } - return initSnippet( - snippetView, - appInfo.loadLabel(pm), - icon); - } - - /** - * Utility method to display application snippet of a new package. - * The content view should have been set on context before invoking this method. - * appSnippet view should include R.id.app_icon and R.id.app_name - * defined on it. - * - * @param pContext context of package that can load the resources - * @param as The resources to be loaded - * @param snippetId view id of app snippet view - */ - @NonNull public static View initSnippetForNewApp(@NonNull Activity pContext, - @NonNull AppSnippet as, int snippetId) { - View appSnippet = pContext.findViewById(snippetId); - if (as.icon != null) { - ((ImageView) appSnippet.findViewById(R.id.app_icon)).setImageDrawable(as.icon); - } - ((TextView)appSnippet.findViewById(R.id.app_name)).setText(as.label); - return appSnippet; - } - - static public class AppSnippet { - @NonNull public CharSequence label; - @Nullable public Drawable icon; - public AppSnippet(@NonNull CharSequence label, @Nullable Drawable icon) { - this.label = label; - this.icon = icon; - } - } - - /** - * Utility method to load application label - * - * @param pContext context of package that can load the resources - * @param appInfo ApplicationInfo object of package whose resources are to be loaded - * @param sourceFile File the package is in - */ - public static AppSnippet getAppSnippet( - Activity pContext, ApplicationInfo appInfo, File sourceFile) { - final String archiveFilePath = sourceFile.getAbsolutePath(); - Resources pRes = pContext.getResources(); - AssetManager assmgr = new AssetManager(); - assmgr.addAssetPath(archiveFilePath); - Resources res = new Resources(assmgr, pRes.getDisplayMetrics(), pRes.getConfiguration()); - CharSequence label = null; - // Try to load the label from the package's resources. If an app has not explicitly - // specified any label, just use the package name. - if (appInfo.labelRes != 0) { - try { - label = res.getText(appInfo.labelRes); - } catch (Resources.NotFoundException e) { - } - } - if (label == null) { - label = (appInfo.nonLocalizedLabel != null) ? - appInfo.nonLocalizedLabel : appInfo.packageName; - } - Drawable icon = null; - // Try to load the icon from the package's resources. If an app has not explicitly - // specified any resource, just use the default icon for now. - try { - if (appInfo.icon != 0) { - try { - icon = res.getDrawable(appInfo.icon); - } catch (Resources.NotFoundException e) { - } - } - if (icon == null) { - icon = pContext.getPackageManager().getDefaultActivityIcon(); - } - } catch (OutOfMemoryError e) { - Log.i(LOG_TAG, "Could not load app icon", e); - } - return new PackageUtil.AppSnippet(label, icon); - } - - /** - * Get the maximum target sdk for a UID. - * - * @param context The context to use - * @param uid The UID requesting the install/uninstall - * - * @return The maximum target SDK or -1 if the uid does not match any packages. - */ - static int getMaxTargetSdkVersionForUid(@NonNull Context context, int uid) { - PackageManager pm = context.getPackageManager(); - final String[] packages = pm.getPackagesForUid(uid); - int targetSdkVersion = -1; - if (packages != null) { - for (String packageName : packages) { - try { - ApplicationInfo info = pm.getApplicationInfo(packageName, 0); - targetSdkVersion = Math.max(targetSdkVersion, info.targetSdkVersion); - } catch (PackageManager.NameNotFoundException e) { - // Ignore and try the next package - } - } - } - return targetSdkVersion; - } -} diff --git a/src/com/android/packageinstaller/RemoveReceiver.java b/src/com/android/packageinstaller/RemoveReceiver.java deleted file mode 100644 index 7d8064dd7..000000000 --- a/src/com/android/packageinstaller/RemoveReceiver.java +++ /dev/null @@ -1,42 +0,0 @@ -/* -** -** Copyright 2007, 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.packageinstaller; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.net.Uri; - -public class RemoveReceiver extends BroadcastReceiver { - - @Override - public void onReceive(Context context, Intent intent) { - if (Intent.ACTION_PACKAGE_FULLY_REMOVED.equals(intent.getAction())) { - Uri uri = intent.getData(); - String pkg = uri != null ? uri.getSchemeSpecificPart() : null; - if (pkg != null) { - SharedPreferences prefs = context.getSharedPreferences( - PackageInstallerActivity.PREFS_ALLOWED_SOURCES, - Context.MODE_PRIVATE); - if (prefs.getBoolean(pkg, false)) { - prefs.edit().remove(pkg).apply(); - } - } - } - } -} diff --git a/src/com/android/packageinstaller/TemporaryFileManager.java b/src/com/android/packageinstaller/TemporaryFileManager.java deleted file mode 100644 index 66e93b310..000000000 --- a/src/com/android/packageinstaller/TemporaryFileManager.java +++ /dev/null @@ -1,95 +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.packageinstaller; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.os.SystemClock; -import androidx.annotation.NonNull; -import android.util.Log; - -import java.io.File; -import java.io.IOException; - -/** - * Manages files of the package installer and resets state during boot. - */ -public class TemporaryFileManager extends BroadcastReceiver { - private static final String LOG_TAG = TemporaryFileManager.class.getSimpleName(); - - /** - * Create a new file to hold a staged file. - * - * @param context The context of the caller - * - * @return A new file - */ - @NonNull - public static File getStagedFile(@NonNull Context context) throws IOException { - return File.createTempFile("package", ".apk", context.getNoBackupFilesDir()); - } - - /** - * Get the file used to store the results of installs. - * - * @param context The context of the caller - * - * @return the file used to store the results of installs - */ - @NonNull - public static File getInstallStateFile(@NonNull Context context) { - return new File(context.getNoBackupFilesDir(), "install_results.xml"); - } - - /** - * Get the file used to store the results of uninstalls. - * - * @param context The context of the caller - * - * @return the file used to store the results of uninstalls - */ - @NonNull - public static File getUninstallStateFile(@NonNull Context context) { - return new File(context.getNoBackupFilesDir(), "uninstall_results.xml"); - } - - @Override - public void onReceive(Context context, Intent intent) { - long systemBootTime = System.currentTimeMillis() - SystemClock.elapsedRealtime(); - - File[] filesOnBoot = context.getNoBackupFilesDir().listFiles(); - - if (filesOnBoot == null) { - return; - } - - for (int i = 0; i < filesOnBoot.length; i++) { - File fileOnBoot = filesOnBoot[i]; - - if (systemBootTime > fileOnBoot.lastModified()) { - boolean wasDeleted = fileOnBoot.delete(); - if (!wasDeleted) { - Log.w(LOG_TAG, "Could not delete " + fileOnBoot.getName() + " onBoot"); - } - } else { - Log.w(LOG_TAG, fileOnBoot.getName() + " was created before onBoot broadcast was " - + "received"); - } - } - } -} diff --git a/src/com/android/packageinstaller/UninstallEventReceiver.java b/src/com/android/packageinstaller/UninstallEventReceiver.java deleted file mode 100644 index ad3cd4c65..000000000 --- a/src/com/android/packageinstaller/UninstallEventReceiver.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * 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. - */ - -package com.android.packageinstaller; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import androidx.annotation.NonNull; - -/** - * Receives uninstall events and persists them using a {@link EventResultPersister}. - */ -public class UninstallEventReceiver extends BroadcastReceiver { - private static final Object sLock = new Object(); - private static EventResultPersister sReceiver; - - /** - * Get the event receiver persisting the results - * - * @return The event receiver. - */ - @NonNull private static EventResultPersister getReceiver(@NonNull Context context) { - synchronized (sLock) { - if (sReceiver == null) { - sReceiver = new EventResultPersister( - TemporaryFileManager.getUninstallStateFile(context)); - } - } - - return sReceiver; - } - - @Override - public void onReceive(Context context, Intent intent) { - getReceiver(context).onEventReceived(context, intent); - } - - /** - * Add an observer. If there is already an event for this id, call back inside of this call. - * - * @param context A context of the current app - * @param id The id the observer is for or {@code GENERATE_NEW_ID} to generate a new one. - * @param observer The observer to call back. - * - * @return The id for this event - */ - static int addObserver(@NonNull Context context, int id, - @NonNull EventResultPersister.EventResultObserver observer) - throws EventResultPersister.OutOfIdsException { - return getReceiver(context).addObserver(id, observer); - } - - /** - * Remove a observer. - * - * @param context A context of the current app - * @param id The id the observer was added for - */ - static void removeObserver(@NonNull Context context, int id) { - getReceiver(context).removeObserver(id); - } - - /** - * @param context A context of the current app - * - * @return A new uninstall id - */ - static int getNewId(@NonNull Context context) throws EventResultPersister.OutOfIdsException { - return getReceiver(context).getNewId(); - } -} diff --git a/src/com/android/packageinstaller/UninstallFinish.java b/src/com/android/packageinstaller/UninstallFinish.java deleted file mode 100644 index 8282c8382..000000000 --- a/src/com/android/packageinstaller/UninstallFinish.java +++ /dev/null @@ -1,265 +0,0 @@ -/* - * 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. - */ - -package com.android.packageinstaller; - -import android.app.Notification; -import android.app.NotificationChannel; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.app.admin.IDevicePolicyManager; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.pm.ApplicationInfo; -import android.content.pm.IPackageManager; -import android.content.pm.PackageInstaller; -import android.content.pm.PackageManager; -import android.content.pm.UserInfo; -import android.graphics.drawable.Icon; -import android.os.RemoteException; -import android.os.ServiceManager; -import android.os.UserHandle; -import android.os.UserManager; -import android.provider.Settings; -import androidx.annotation.NonNull; -import android.util.Log; -import android.widget.Toast; - -import java.util.List; - -/** - * Finish an uninstallation and show Toast on success or failure notification. - */ -public class UninstallFinish extends BroadcastReceiver { - private static final String LOG_TAG = UninstallFinish.class.getSimpleName(); - - private static final String UNINSTALL_FAILURE_CHANNEL = "uninstall failure"; - - static final String EXTRA_UNINSTALL_ID = "com.android.packageinstaller.extra.UNINSTALL_ID"; - static final String EXTRA_APP_LABEL = "com.android.packageinstaller.extra.APP_LABEL"; - - @Override - public void onReceive(Context context, Intent intent) { - int returnCode = intent.getIntExtra(PackageInstaller.EXTRA_STATUS, 0); - - Log.i(LOG_TAG, "Uninstall finished extras=" + intent.getExtras()); - - if (returnCode == PackageInstaller.STATUS_PENDING_USER_ACTION) { - context.startActivity(intent.getParcelableExtra(Intent.EXTRA_INTENT)); - return; - } - - int uninstallId = intent.getIntExtra(EXTRA_UNINSTALL_ID, 0); - ApplicationInfo appInfo = intent.getParcelableExtra( - PackageUtil.INTENT_ATTR_APPLICATION_INFO); - String appLabel = intent.getStringExtra(EXTRA_APP_LABEL); - boolean allUsers = intent.getBooleanExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, false); - - NotificationManager notificationManager = - context.getSystemService(NotificationManager.class); - UserManager userManager = context.getSystemService(UserManager.class); - - NotificationChannel uninstallFailureChannel = new NotificationChannel( - UNINSTALL_FAILURE_CHANNEL, - context.getString(R.string.uninstall_failure_notification_channel), - NotificationManager.IMPORTANCE_DEFAULT); - notificationManager.createNotificationChannel(uninstallFailureChannel); - - Notification.Builder uninstallFailedNotification = new Notification.Builder(context, - UNINSTALL_FAILURE_CHANNEL); - - switch (returnCode) { - case PackageInstaller.STATUS_SUCCESS: - notificationManager.cancel(uninstallId); - - Toast.makeText(context, context.getString(R.string.uninstall_done_app, appLabel), - Toast.LENGTH_LONG).show(); - return; - case PackageInstaller.STATUS_FAILURE_BLOCKED: { - int legacyStatus = intent.getIntExtra(PackageInstaller.EXTRA_LEGACY_STATUS, 0); - - switch (legacyStatus) { - case PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER: { - IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface( - ServiceManager.getService(Context.DEVICE_POLICY_SERVICE)); - // Find out if the package is an active admin for some non-current user. - int myUserId = UserHandle.myUserId(); - UserInfo otherBlockingUser = null; - for (UserInfo user : userManager.getUsers()) { - // We only catch the case when the user in question is neither the - // current user nor its profile. - if (isProfileOfOrSame(userManager, myUserId, user.id)) { - continue; - } - - try { - if (dpm.packageHasActiveAdmins(appInfo.packageName, user.id)) { - otherBlockingUser = user; - break; - } - } catch (RemoteException e) { - Log.e(LOG_TAG, "Failed to talk to package manager", e); - } - } - if (otherBlockingUser == null) { - Log.d(LOG_TAG, "Uninstall failed because " + appInfo.packageName - + " is a device admin"); - - addDeviceManagerButton(context, uninstallFailedNotification); - setBigText(uninstallFailedNotification, context.getString( - R.string.uninstall_failed_device_policy_manager)); - } else { - Log.d(LOG_TAG, "Uninstall failed because " + appInfo.packageName - + " is a device admin of user " + otherBlockingUser); - - setBigText(uninstallFailedNotification, String.format(context.getString( - R.string.uninstall_failed_device_policy_manager_of_user), - otherBlockingUser.name)); - } - break; - } - case PackageManager.DELETE_FAILED_OWNER_BLOCKED: { - IPackageManager packageManager = IPackageManager.Stub.asInterface( - ServiceManager.getService("package")); - - List users = userManager.getUsers(); - int blockingUserId = UserHandle.USER_NULL; - for (int i = 0; i < users.size(); ++i) { - final UserInfo user = users.get(i); - try { - if (packageManager.getBlockUninstallForUser(appInfo.packageName, - user.id)) { - blockingUserId = user.id; - break; - } - } catch (RemoteException e) { - // Shouldn't happen. - Log.e(LOG_TAG, "Failed to talk to package manager", e); - } - } - - int myUserId = UserHandle.myUserId(); - if (isProfileOfOrSame(userManager, myUserId, blockingUserId)) { - addDeviceManagerButton(context, uninstallFailedNotification); - } else { - addManageUsersButton(context, uninstallFailedNotification); - } - - if (blockingUserId == UserHandle.USER_NULL) { - Log.d(LOG_TAG, - "Uninstall failed for " + appInfo.packageName + " with code " - + returnCode + " no blocking user"); - } else if (blockingUserId == UserHandle.USER_SYSTEM) { - setBigText(uninstallFailedNotification, - context.getString(R.string.uninstall_blocked_device_owner)); - } else { - if (allUsers) { - setBigText(uninstallFailedNotification, - context.getString( - R.string.uninstall_all_blocked_profile_owner)); - } else { - setBigText(uninstallFailedNotification, context.getString( - R.string.uninstall_blocked_profile_owner)); - } - } - break; - } - default: - Log.d(LOG_TAG, "Uninstall blocked for " + appInfo.packageName - + " with legacy code " + legacyStatus); - } break; - } - default: - Log.d(LOG_TAG, "Uninstall failed for " + appInfo.packageName + " with code " - + returnCode); - break; - } - - uninstallFailedNotification.setContentTitle( - context.getString(R.string.uninstall_failed_app, appLabel)); - uninstallFailedNotification.setOngoing(false); - uninstallFailedNotification.setSmallIcon(R.drawable.ic_error); - notificationManager.notify(uninstallId, uninstallFailedNotification.build()); - } - - /** - * Is a profile part of a user? - * - * @param userManager The user manager - * @param userId The id of the user - * @param profileId The id of the profile - * - * @return If the profile is part of the user or the profile parent of the user - */ - private boolean isProfileOfOrSame(@NonNull UserManager userManager, int userId, int profileId) { - if (userId == profileId) { - return true; - } - - UserInfo parentUser = userManager.getProfileParent(profileId); - return parentUser != null && parentUser.id == userId; - } - - /** - * Set big text for the notification. - * - * @param builder The builder of the notification - * @param text The text to set. - */ - private void setBigText(@NonNull Notification.Builder builder, - @NonNull CharSequence text) { - builder.setStyle(new Notification.BigTextStyle().bigText(text)); - } - - /** - * Add a button to the notification that links to the user management. - * - * @param context The context the notification is created in - * @param builder The builder of the notification - */ - private void addManageUsersButton(@NonNull Context context, - @NonNull Notification.Builder builder) { - Intent intent = new Intent(Settings.ACTION_USER_SETTINGS); - intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_NEW_TASK); - - builder.addAction((new Notification.Action.Builder( - Icon.createWithResource(context, R.drawable.ic_settings_multiuser), - context.getString(R.string.manage_users), - PendingIntent.getActivity(context, 0, intent, - PendingIntent.FLAG_UPDATE_CURRENT))).build()); - } - - /** - * Add a button to the notification that links to the device policy management. - * - * @param context The context the notification is created in - * @param builder The builder of the notification - */ - private void addDeviceManagerButton(@NonNull Context context, - @NonNull Notification.Builder builder) { - Intent intent = new Intent(); - intent.setClassName("com.android.settings", - "com.android.settings.Settings$DeviceAdminSettingsActivity"); - intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_NEW_TASK); - - builder.addAction((new Notification.Action.Builder( - Icon.createWithResource(context, R.drawable.ic_lock), - context.getString(R.string.manage_device_administrators), - PendingIntent.getActivity(context, 0, intent, - PendingIntent.FLAG_UPDATE_CURRENT))).build()); - } -} diff --git a/src/com/android/packageinstaller/UninstallUninstalling.java b/src/com/android/packageinstaller/UninstallUninstalling.java deleted file mode 100644 index e27186ba5..000000000 --- a/src/com/android/packageinstaller/UninstallUninstalling.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * 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. - */ - -package com.android.packageinstaller; - -import android.app.Activity; -import android.app.ActivityThread; -import android.app.AlertDialog; -import android.app.Dialog; -import android.app.DialogFragment; -import android.app.Fragment; -import android.app.FragmentTransaction; -import android.app.PendingIntent; -import android.content.Intent; -import android.content.pm.ApplicationInfo; -import android.content.pm.IPackageDeleteObserver2; -import android.content.pm.PackageInstaller; -import android.content.pm.PackageManager; -import android.content.pm.VersionedPackage; -import android.os.Bundle; -import android.os.IBinder; -import android.os.RemoteException; -import android.os.UserHandle; -import androidx.annotation.Nullable; -import android.util.Log; -import android.widget.Toast; - -/** - * Start an uninstallation, show a dialog while uninstalling and return result to the caller. - */ -public class UninstallUninstalling extends Activity implements - EventResultPersister.EventResultObserver { - private static final String LOG_TAG = UninstallUninstalling.class.getSimpleName(); - - private static final String UNINSTALL_ID = "com.android.packageinstaller.UNINSTALL_ID"; - private static final String BROADCAST_ACTION = - "com.android.packageinstaller.ACTION_UNINSTALL_COMMIT"; - - static final String EXTRA_APP_LABEL = "com.android.packageinstaller.extra.APP_LABEL"; - - private int mUninstallId; - private ApplicationInfo mAppInfo; - private IBinder mCallback; - private boolean mReturnResult; - private String mLabel; - - @Override - protected void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - setFinishOnTouchOutside(false); - - mAppInfo = getIntent().getParcelableExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO); - mCallback = getIntent().getIBinderExtra(PackageInstaller.EXTRA_CALLBACK); - mReturnResult = getIntent().getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false); - mLabel = getIntent().getStringExtra(EXTRA_APP_LABEL); - - try { - if (savedInstanceState == null) { - boolean allUsers = getIntent().getBooleanExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, - false); - UserHandle user = getIntent().getParcelableExtra(Intent.EXTRA_USER); - - // Show dialog, which is the whole UI - FragmentTransaction transaction = getFragmentManager().beginTransaction(); - Fragment prev = getFragmentManager().findFragmentByTag("dialog"); - if (prev != null) { - transaction.remove(prev); - } - DialogFragment dialog = new UninstallUninstallingFragment(); - dialog.setCancelable(false); - dialog.show(transaction, "dialog"); - - mUninstallId = UninstallEventReceiver.addObserver(this, - EventResultPersister.GENERATE_NEW_ID, this); - - Intent broadcastIntent = new Intent(BROADCAST_ACTION); - broadcastIntent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND); - broadcastIntent.putExtra(EventResultPersister.EXTRA_ID, mUninstallId); - broadcastIntent.setPackage(getPackageName()); - - PendingIntent pendingIntent = PendingIntent.getBroadcast(this, mUninstallId, - broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT); - - try { - ActivityThread.getPackageManager().getPackageInstaller().uninstall( - new VersionedPackage(mAppInfo.packageName, - PackageManager.VERSION_CODE_HIGHEST), - getPackageName(), allUsers ? PackageManager.DELETE_ALL_USERS : 0, - pendingIntent.getIntentSender(), user.getIdentifier()); - } catch (RemoteException e) { - e.rethrowFromSystemServer(); - } - } else { - mUninstallId = savedInstanceState.getInt(UNINSTALL_ID); - UninstallEventReceiver.addObserver(this, mUninstallId, this); - } - } catch (EventResultPersister.OutOfIdsException | IllegalArgumentException e) { - Log.e(LOG_TAG, "Fails to start uninstall", e); - onResult(PackageInstaller.STATUS_FAILURE, PackageManager.DELETE_FAILED_INTERNAL_ERROR, - null); - } - } - - @Override - protected void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - - outState.putInt(UNINSTALL_ID, mUninstallId); - } - - @Override - public void onBackPressed() { - // do nothing - } - - @Override - public void onResult(int status, int legacyStatus, @Nullable String message) { - if (mCallback != null) { - // The caller will be informed about the result via a callback - final IPackageDeleteObserver2 observer = IPackageDeleteObserver2.Stub - .asInterface(mCallback); - try { - observer.onPackageDeleted(mAppInfo.packageName, legacyStatus, message); - } catch (RemoteException ignored) { - } - } else if (mReturnResult) { - // The caller will be informed about the result and might decide to display it - Intent result = new Intent(); - - result.putExtra(Intent.EXTRA_INSTALL_RESULT, legacyStatus); - setResult(status == PackageInstaller.STATUS_SUCCESS ? Activity.RESULT_OK - : Activity.RESULT_FIRST_USER, result); - } else { - // This is the rare case that the caller did not ask for the result, but wanted to be - // notified via onActivityResult when the installation finishes - if (status != PackageInstaller.STATUS_SUCCESS) { - Toast.makeText(this, getString(R.string.uninstall_failed_app, mLabel), - Toast.LENGTH_LONG).show(); - } - } - finish(); - } - - @Override - protected void onDestroy() { - UninstallEventReceiver.removeObserver(this, mUninstallId); - - super.onDestroy(); - } - - /** - * Dialog that shows that the app is uninstalling. - */ - public static class UninstallUninstallingFragment extends DialogFragment { - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(getActivity()); - - dialogBuilder.setCancelable(false); - dialogBuilder.setMessage(getActivity().getString(R.string.uninstalling_app, - ((UninstallUninstalling) getActivity()).mLabel)); - - Dialog dialog = dialogBuilder.create(); - dialog.setCanceledOnTouchOutside(false); - - return dialog; - } - } -} diff --git a/src/com/android/packageinstaller/UninstallerActivity.java b/src/com/android/packageinstaller/UninstallerActivity.java deleted file mode 100755 index d5df9f52d..000000000 --- a/src/com/android/packageinstaller/UninstallerActivity.java +++ /dev/null @@ -1,395 +0,0 @@ -/* -** -** Copyright 2007, 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.packageinstaller; - -import static android.app.AppOpsManager.MODE_ALLOWED; - -import static com.android.packageinstaller.PackageUtil.getMaxTargetSdkVersionForUid; - -import android.Manifest; -import android.app.Activity; -import android.app.ActivityManager; -import android.app.ActivityThread; -import android.app.AppGlobals; -import android.app.AppOpsManager; -import android.app.DialogFragment; -import android.app.Fragment; -import android.app.FragmentTransaction; -import android.app.Notification; -import android.app.NotificationChannel; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.pm.ActivityInfo; -import android.content.pm.ApplicationInfo; -import android.content.pm.IPackageDeleteObserver2; -import android.content.pm.IPackageManager; -import android.content.pm.PackageInstaller; -import android.content.pm.PackageManager; -import android.content.pm.VersionedPackage; -import android.content.res.Configuration; -import android.net.Uri; -import android.os.Build; -import android.os.Bundle; -import android.os.IBinder; -import android.os.RemoteException; -import android.os.ServiceManager; -import android.os.UserHandle; -import android.os.UserManager; -import androidx.annotation.NonNull; -import androidx.annotation.StringRes; -import android.util.Log; - -import com.android.packageinstaller.handheld.ErrorDialogFragment; -import com.android.packageinstaller.handheld.UninstallAlertDialogFragment; -import com.android.packageinstaller.television.ErrorFragment; -import com.android.packageinstaller.television.UninstallAlertFragment; -import com.android.packageinstaller.television.UninstallAppProgress; - -import java.util.List; - -/* - * This activity presents UI to uninstall an application. Usually launched with intent - * Intent.ACTION_UNINSTALL_PKG_COMMAND and attribute - * com.android.packageinstaller.PackageName set to the application package name - */ -public class UninstallerActivity extends Activity { - private static final String TAG = "UninstallerActivity"; - - private static final String UNINSTALLING_CHANNEL = "uninstalling"; - - public static class DialogInfo { - public ApplicationInfo appInfo; - public ActivityInfo activityInfo; - public boolean allUsers; - public UserHandle user; - public IBinder callback; - } - - private String mPackageName; - private DialogInfo mDialogInfo; - - @Override - public void onCreate(Bundle icicle) { - // Never restore any state, esp. never create any fragments. The data in the fragment might - // be stale, if e.g. the app was uninstalled while the activity was destroyed. - super.onCreate(null); - - try { - int callingUid = ActivityManager.getService().getLaunchedFromUid(getActivityToken()); - - String callingPackage = getPackageNameForUid(callingUid); - if (callingPackage == null) { - Log.e(TAG, "Package not found for originating uid " + callingUid); - setResult(Activity.RESULT_FIRST_USER); - finish(); - return; - } else { - AppOpsManager appOpsManager = (AppOpsManager) getSystemService( - Context.APP_OPS_SERVICE); - if (appOpsManager.noteOpNoThrow( - AppOpsManager.OPSTR_REQUEST_DELETE_PACKAGES, callingUid, callingPackage) - != MODE_ALLOWED) { - Log.e(TAG, "Install from uid " + callingUid + " disallowed by AppOps"); - setResult(Activity.RESULT_FIRST_USER); - finish(); - return; - } - } - - if (getMaxTargetSdkVersionForUid(this, callingUid) - >= Build.VERSION_CODES.P && AppGlobals.getPackageManager().checkUidPermission( - Manifest.permission.REQUEST_DELETE_PACKAGES, callingUid) - != PackageManager.PERMISSION_GRANTED - && AppGlobals.getPackageManager().checkUidPermission( - Manifest.permission.DELETE_PACKAGES, callingUid) - != PackageManager.PERMISSION_GRANTED) { - Log.e(TAG, "Uid " + callingUid + " does not have " - + Manifest.permission.REQUEST_DELETE_PACKAGES + " or " - + Manifest.permission.DELETE_PACKAGES); - - setResult(Activity.RESULT_FIRST_USER); - finish(); - return; - } - } catch (RemoteException ex) { - // Cannot reach Package/ActivityManager. Aborting uninstall. - Log.e(TAG, "Could not determine the launching uid."); - - setResult(Activity.RESULT_FIRST_USER); - finish(); - return; - } - - // Get intent information. - // We expect an intent with URI of the form package://# - // className is optional; if specified, it is the activity the user chose to uninstall - final Intent intent = getIntent(); - final Uri packageUri = intent.getData(); - if (packageUri == null) { - Log.e(TAG, "No package URI in intent"); - showAppNotFound(); - return; - } - mPackageName = packageUri.getEncodedSchemeSpecificPart(); - if (mPackageName == null) { - Log.e(TAG, "Invalid package name in URI: " + packageUri); - showAppNotFound(); - return; - } - - final IPackageManager pm = IPackageManager.Stub.asInterface( - ServiceManager.getService("package")); - - mDialogInfo = new DialogInfo(); - - mDialogInfo.allUsers = intent.getBooleanExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, false); - if (mDialogInfo.allUsers && !UserManager.get(this).isAdminUser()) { - Log.e(TAG, "Only admin user can request uninstall for all users"); - showUserIsNotAllowed(); - return; - } - mDialogInfo.user = intent.getParcelableExtra(Intent.EXTRA_USER); - if (mDialogInfo.user == null) { - mDialogInfo.user = android.os.Process.myUserHandle(); - } else { - UserManager userManager = (UserManager) getSystemService(Context.USER_SERVICE); - List profiles = userManager.getUserProfiles(); - if (!profiles.contains(mDialogInfo.user)) { - Log.e(TAG, "User " + android.os.Process.myUserHandle() + " can't request uninstall " - + "for user " + mDialogInfo.user); - showUserIsNotAllowed(); - return; - } - } - - mDialogInfo.callback = intent.getIBinderExtra(PackageInstaller.EXTRA_CALLBACK); - - try { - mDialogInfo.appInfo = pm.getApplicationInfo(mPackageName, - PackageManager.MATCH_ANY_USER, mDialogInfo.user.getIdentifier()); - } catch (RemoteException e) { - Log.e(TAG, "Unable to get packageName. Package manager is dead?"); - } - - if (mDialogInfo.appInfo == null) { - Log.e(TAG, "Invalid packageName: " + mPackageName); - showAppNotFound(); - return; - } - - // The class name may have been specified (e.g. when deleting an app from all apps) - final String className = packageUri.getFragment(); - if (className != null) { - try { - mDialogInfo.activityInfo = pm.getActivityInfo( - new ComponentName(mPackageName, className), 0, - mDialogInfo.user.getIdentifier()); - } catch (RemoteException e) { - Log.e(TAG, "Unable to get className. Package manager is dead?"); - // Continue as the ActivityInfo isn't critical. - } - } - - showConfirmationDialog(); - } - - public DialogInfo getDialogInfo() { - return mDialogInfo; - } - - private void showConfirmationDialog() { - if (isTv()) { - showContentFragment(new UninstallAlertFragment(), 0, 0); - } else { - showDialogFragment(new UninstallAlertDialogFragment(), 0, 0); - } - } - - private void showAppNotFound() { - if (isTv()) { - showContentFragment(new ErrorFragment(), R.string.app_not_found_dlg_title, - R.string.app_not_found_dlg_text); - } else { - showDialogFragment(new ErrorDialogFragment(), R.string.app_not_found_dlg_title, - R.string.app_not_found_dlg_text); - } - } - - private void showUserIsNotAllowed() { - if (isTv()) { - showContentFragment(new ErrorFragment(), - R.string.user_is_not_allowed_dlg_title, R.string.user_is_not_allowed_dlg_text); - } else { - showDialogFragment(new ErrorDialogFragment(), 0, R.string.user_is_not_allowed_dlg_text); - } - } - - private void showGenericError() { - if (isTv()) { - showContentFragment(new ErrorFragment(), - R.string.generic_error_dlg_title, R.string.generic_error_dlg_text); - } else { - showDialogFragment(new ErrorDialogFragment(), 0, R.string.generic_error_dlg_text); - } - } - - private boolean isTv() { - return (getResources().getConfiguration().uiMode & Configuration.UI_MODE_TYPE_MASK) - == Configuration.UI_MODE_TYPE_TELEVISION; - } - - private void showContentFragment(@NonNull Fragment fragment, @StringRes int title, - @StringRes int text) { - Bundle args = new Bundle(); - args.putInt(ErrorFragment.TITLE, title); - args.putInt(ErrorFragment.TEXT, text); - fragment.setArguments(args); - - getFragmentManager().beginTransaction() - .replace(android.R.id.content, fragment) - .commit(); - } - - private void showDialogFragment(@NonNull DialogFragment fragment, - @StringRes int title, @StringRes int text) { - FragmentTransaction ft = getFragmentManager().beginTransaction(); - Fragment prev = getFragmentManager().findFragmentByTag("dialog"); - if (prev != null) { - ft.remove(prev); - } - - Bundle args = new Bundle(); - if (title != 0) { - args.putInt(ErrorDialogFragment.TITLE, title); - } - args.putInt(ErrorDialogFragment.TEXT, text); - - fragment.setArguments(args); - fragment.show(ft, "dialog"); - } - - public void startUninstallProgress() { - boolean returnResult = getIntent().getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false); - CharSequence label = mDialogInfo.appInfo.loadSafeLabel(getPackageManager()); - - if (isTv()) { - Intent newIntent = new Intent(Intent.ACTION_VIEW); - newIntent.putExtra(Intent.EXTRA_USER, mDialogInfo.user); - newIntent.putExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, mDialogInfo.allUsers); - newIntent.putExtra(PackageInstaller.EXTRA_CALLBACK, mDialogInfo.callback); - newIntent.putExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO, mDialogInfo.appInfo); - - if (returnResult) { - newIntent.putExtra(Intent.EXTRA_RETURN_RESULT, true); - newIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT); - } - - newIntent.setClass(this, UninstallAppProgress.class); - startActivity(newIntent); - } else if (returnResult || mDialogInfo.callback != null || getCallingActivity() != null) { - Intent newIntent = new Intent(this, UninstallUninstalling.class); - - newIntent.putExtra(Intent.EXTRA_USER, mDialogInfo.user); - newIntent.putExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, mDialogInfo.allUsers); - newIntent.putExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO, mDialogInfo.appInfo); - newIntent.putExtra(UninstallUninstalling.EXTRA_APP_LABEL, label); - newIntent.putExtra(PackageInstaller.EXTRA_CALLBACK, mDialogInfo.callback); - - if (returnResult) { - newIntent.putExtra(Intent.EXTRA_RETURN_RESULT, true); - } - - if (returnResult || getCallingActivity() != null) { - newIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT); - } - - startActivity(newIntent); - } else { - int uninstallId; - try { - uninstallId = UninstallEventReceiver.getNewId(this); - } catch (EventResultPersister.OutOfIdsException e) { - showGenericError(); - return; - } - - Intent broadcastIntent = new Intent(this, UninstallFinish.class); - - broadcastIntent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND); - broadcastIntent.putExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, mDialogInfo.allUsers); - broadcastIntent.putExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO, mDialogInfo.appInfo); - broadcastIntent.putExtra(UninstallFinish.EXTRA_APP_LABEL, label); - broadcastIntent.putExtra(UninstallFinish.EXTRA_UNINSTALL_ID, uninstallId); - - PendingIntent pendingIntent = PendingIntent.getBroadcast(this, uninstallId, - broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT); - - NotificationManager notificationManager = getSystemService(NotificationManager.class); - NotificationChannel uninstallingChannel = new NotificationChannel(UNINSTALLING_CHANNEL, - getString(R.string.uninstalling_notification_channel), - NotificationManager.IMPORTANCE_MIN); - notificationManager.createNotificationChannel(uninstallingChannel); - - Notification uninstallingNotification = - (new Notification.Builder(this, UNINSTALLING_CHANNEL)) - .setSmallIcon(R.drawable.ic_remove).setProgress(0, 1, true) - .setContentTitle(getString(R.string.uninstalling_app, label)).setOngoing(true) - .build(); - - notificationManager.notify(uninstallId, uninstallingNotification); - - try { - Log.i(TAG, "Uninstalling extras=" + broadcastIntent.getExtras()); - - ActivityThread.getPackageManager().getPackageInstaller().uninstall( - new VersionedPackage(mDialogInfo.appInfo.packageName, - PackageManager.VERSION_CODE_HIGHEST), - getPackageName(), mDialogInfo.allUsers - ? PackageManager.DELETE_ALL_USERS : 0, - pendingIntent.getIntentSender(), mDialogInfo.user.getIdentifier()); - } catch (Exception e) { - notificationManager.cancel(uninstallId); - - Log.e(TAG, "Cannot start uninstall", e); - showGenericError(); - } - } - } - - public void dispatchAborted() { - if (mDialogInfo != null && mDialogInfo.callback != null) { - final IPackageDeleteObserver2 observer = IPackageDeleteObserver2.Stub.asInterface( - mDialogInfo.callback); - try { - observer.onPackageDeleted(mPackageName, - PackageManager.DELETE_FAILED_ABORTED, "Cancelled by user"); - } catch (RemoteException ignored) { - } - } - } - - private String getPackageNameForUid(int sourceUid) { - String[] packagesForUid = getPackageManager().getPackagesForUid(sourceUid); - if (packagesForUid == null) { - return null; - } - return packagesForUid[0]; - } -} diff --git a/src/com/android/packageinstaller/handheld/ErrorDialogFragment.java b/src/com/android/packageinstaller/handheld/ErrorDialogFragment.java deleted file mode 100644 index 4ec6a2d68..000000000 --- a/src/com/android/packageinstaller/handheld/ErrorDialogFragment.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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 - */ - -package com.android.packageinstaller.handheld; - -import android.app.Activity; -import android.app.AlertDialog; -import android.app.Dialog; -import android.app.DialogFragment; -import android.content.DialogInterface; -import android.os.Bundle; - -import com.android.packageinstaller.UninstallerActivity; - -public class ErrorDialogFragment extends DialogFragment { - public static final String TITLE = "com.android.packageinstaller.arg.title"; - public static final String TEXT = "com.android.packageinstaller.arg.text"; - - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - AlertDialog.Builder b = new AlertDialog.Builder(getActivity()) - .setMessage(getArguments().getInt(TEXT)) - .setPositiveButton(android.R.string.ok, null); - - if (getArguments().containsKey(TITLE)) { - b.setTitle(getArguments().getInt(TITLE)); - } - - return b.create(); - } - - @Override - public void onDismiss(DialogInterface dialog) { - super.onDismiss(dialog); - if (isAdded()) { - if (getActivity() instanceof UninstallerActivity) { - ((UninstallerActivity) getActivity()).dispatchAborted(); - } - - getActivity().setResult(Activity.RESULT_FIRST_USER); - getActivity().finish(); - } - } -} diff --git a/src/com/android/packageinstaller/handheld/UninstallAlertDialogFragment.java b/src/com/android/packageinstaller/handheld/UninstallAlertDialogFragment.java deleted file mode 100644 index e0ca74eb9..000000000 --- a/src/com/android/packageinstaller/handheld/UninstallAlertDialogFragment.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * 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 - */ - -package com.android.packageinstaller.handheld; - -import android.app.AlertDialog; -import android.app.Dialog; -import android.app.DialogFragment; -import android.content.DialogInterface; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.content.pm.UserInfo; -import android.os.Bundle; -import android.os.UserManager; - -import com.android.packageinstaller.R; -import com.android.packageinstaller.UninstallerActivity; - -public class UninstallAlertDialogFragment extends DialogFragment implements - DialogInterface.OnClickListener { - - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - final PackageManager pm = getActivity().getPackageManager(); - final UninstallerActivity.DialogInfo dialogInfo = - ((UninstallerActivity) getActivity()).getDialogInfo(); - final CharSequence appLabel = dialogInfo.appInfo.loadSafeLabel(pm); - AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(getActivity()); - StringBuilder messageBuilder = new StringBuilder(); - - // If the Activity label differs from the App label, then make sure the user - // knows the Activity belongs to the App being uninstalled. - if (dialogInfo.activityInfo != null) { - final CharSequence activityLabel = dialogInfo.activityInfo.loadSafeLabel(pm); - if (!activityLabel.equals(appLabel)) { - messageBuilder.append( - getString(R.string.uninstall_activity_text, activityLabel)); - messageBuilder.append(" ").append(appLabel).append(".\n\n"); - } - } - - final boolean isUpdate = - ((dialogInfo.appInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0); - UserManager userManager = UserManager.get(getActivity()); - if (isUpdate) { - if (isSingleUser(userManager)) { - messageBuilder.append(getString(R.string.uninstall_update_text)); - } else { - messageBuilder.append(getString(R.string.uninstall_update_text_multiuser)); - } - } else { - if (dialogInfo.allUsers && !isSingleUser(userManager)) { - messageBuilder.append(getString(R.string.uninstall_application_text_all_users)); - } else if (!dialogInfo.user.equals(android.os.Process.myUserHandle())) { - UserInfo userInfo = userManager.getUserInfo(dialogInfo.user.getIdentifier()); - messageBuilder.append( - getString(R.string.uninstall_application_text_user, userInfo.name)); - } else { - messageBuilder.append(getString(R.string.uninstall_application_text)); - } - } - - dialogBuilder.setTitle(appLabel); - dialogBuilder.setPositiveButton(android.R.string.ok, this); - dialogBuilder.setNegativeButton(android.R.string.cancel, this); - dialogBuilder.setMessage(messageBuilder.toString()); - return dialogBuilder.create(); - } - - @Override - public void onClick(DialogInterface dialog, int which) { - if (which == Dialog.BUTTON_POSITIVE) { - ((UninstallerActivity) getActivity()).startUninstallProgress(); - } else { - ((UninstallerActivity) getActivity()).dispatchAborted(); - } - } - - @Override - public void onDismiss(DialogInterface dialog) { - super.onDismiss(dialog); - if (isAdded()) { - getActivity().finish(); - } - } - - /** - * Returns whether there is only one user on this device, not including - * the system-only user. - */ - private boolean isSingleUser(UserManager userManager) { - final int userCount = userManager.getUserCount(); - return userCount == 1 - || (UserManager.isSplitSystemUser() && userCount == 2); - } -} diff --git a/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java b/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java index 6b3a76071..618d9a05b 100644 --- a/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java +++ b/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java @@ -36,7 +36,7 @@ import android.os.Process; import android.os.UserHandle; import android.util.ArrayMap; -import com.android.packageinstaller.R; +import com.android.permissioncontroller.R; import com.android.packageinstaller.permission.utils.ArrayUtils; import com.android.packageinstaller.permission.utils.LocationUtils; diff --git a/src/com/android/packageinstaller/permission/model/PermissionApps.java b/src/com/android/packageinstaller/permission/model/PermissionApps.java index d0bf5853b..60c5da77a 100644 --- a/src/com/android/packageinstaller/permission/model/PermissionApps.java +++ b/src/com/android/packageinstaller/permission/model/PermissionApps.java @@ -32,7 +32,7 @@ import android.util.IconDrawableFactory; import android.util.Log; import android.util.SparseArray; -import com.android.packageinstaller.R; +import com.android.permissioncontroller.R; import com.android.packageinstaller.permission.utils.Utils; import java.util.ArrayList; diff --git a/src/com/android/packageinstaller/permission/model/PermissionGroups.java b/src/com/android/packageinstaller/permission/model/PermissionGroups.java index 491b05990..d7725a2a2 100644 --- a/src/com/android/packageinstaller/permission/model/PermissionGroups.java +++ b/src/com/android/packageinstaller/permission/model/PermissionGroups.java @@ -33,7 +33,7 @@ import android.graphics.drawable.Drawable; import android.os.Bundle; import android.util.ArraySet; -import com.android.packageinstaller.R; +import com.android.permissioncontroller.R; import com.android.packageinstaller.permission.utils.Utils; import java.util.ArrayList; diff --git a/src/com/android/packageinstaller/permission/ui/ButtonBarLayout.java b/src/com/android/packageinstaller/permission/ui/ButtonBarLayout.java index 8b0f219b9..061c85a80 100644 --- a/src/com/android/packageinstaller/permission/ui/ButtonBarLayout.java +++ b/src/com/android/packageinstaller/permission/ui/ButtonBarLayout.java @@ -22,7 +22,7 @@ import android.view.Gravity; import android.view.View; import android.widget.LinearLayout; -import com.android.packageinstaller.R; +import com.android.permissioncontroller.R; /** * An extension of LinearLayout that automatically switches to vertical diff --git a/src/com/android/packageinstaller/permission/ui/ConfirmActionDialogFragment.java b/src/com/android/packageinstaller/permission/ui/ConfirmActionDialogFragment.java index c13f63098..cd05efed4 100644 --- a/src/com/android/packageinstaller/permission/ui/ConfirmActionDialogFragment.java +++ b/src/com/android/packageinstaller/permission/ui/ConfirmActionDialogFragment.java @@ -23,7 +23,7 @@ import android.os.Bundle; import androidx.fragment.app.DialogFragment; -import com.android.packageinstaller.R; +import com.android.permissioncontroller.R; public final class ConfirmActionDialogFragment extends DialogFragment { public static final String ARG_MESSAGE = "MESSAGE"; diff --git a/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java b/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java index 51bd2836a..dc24109fc 100644 --- a/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java +++ b/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java @@ -50,7 +50,7 @@ import android.view.WindowManager; import com.android.internal.content.PackageMonitor; import com.android.internal.logging.nano.MetricsProto; import com.android.packageinstaller.DeviceUtils; -import com.android.packageinstaller.R; +import com.android.permissioncontroller.R; import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.model.AppPermissions; import com.android.packageinstaller.permission.model.Permission; diff --git a/src/com/android/packageinstaller/permission/ui/GrantPermissionsWatchViewHandler.java b/src/com/android/packageinstaller/permission/ui/GrantPermissionsWatchViewHandler.java index f2251c1f3..3dcca2d41 100644 --- a/src/com/android/packageinstaller/permission/ui/GrantPermissionsWatchViewHandler.java +++ b/src/com/android/packageinstaller/permission/ui/GrantPermissionsWatchViewHandler.java @@ -21,7 +21,7 @@ import android.widget.Space; import androidx.wear.ble.view.AcceptDenyDialog; import androidx.wear.ble.view.WearableDialogHelper; -import com.android.packageinstaller.R; +import com.android.permissioncontroller.R; /** * Watch-specific view handler for the grant permissions activity. diff --git a/src/com/android/packageinstaller/permission/ui/ManagePermissionsActivity.java b/src/com/android/packageinstaller/permission/ui/ManagePermissionsActivity.java index 712b860c5..19d84d9f8 100644 --- a/src/com/android/packageinstaller/permission/ui/ManagePermissionsActivity.java +++ b/src/com/android/packageinstaller/permission/ui/ManagePermissionsActivity.java @@ -23,7 +23,7 @@ import android.util.Log; import android.view.MenuItem; import com.android.packageinstaller.DeviceUtils; -import com.android.packageinstaller.R; +import com.android.permissioncontroller.R; import com.android.packageinstaller.permission.ui.handheld.ManageStandardPermissionsFragment; import com.android.packageinstaller.permission.ui.wear.AppPermissionsFragmentWear; diff --git a/src/com/android/packageinstaller/permission/ui/OverlayWarningDialog.java b/src/com/android/packageinstaller/permission/ui/OverlayWarningDialog.java index 61734b470..9935dcb83 100644 --- a/src/com/android/packageinstaller/permission/ui/OverlayWarningDialog.java +++ b/src/com/android/packageinstaller/permission/ui/OverlayWarningDialog.java @@ -27,7 +27,7 @@ import android.os.Bundle; import android.provider.Settings; import android.util.Log; -import com.android.packageinstaller.R; +import com.android.permissioncontroller.R; public class OverlayWarningDialog extends Activity implements OnClickListener, OnDismissListener { diff --git a/src/com/android/packageinstaller/permission/ui/ReviewPermissionsActivity.java b/src/com/android/packageinstaller/permission/ui/ReviewPermissionsActivity.java index e4929c7e9..b237cf6d9 100644 --- a/src/com/android/packageinstaller/permission/ui/ReviewPermissionsActivity.java +++ b/src/com/android/packageinstaller/permission/ui/ReviewPermissionsActivity.java @@ -26,7 +26,7 @@ import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; import com.android.packageinstaller.DeviceUtils; -import com.android.packageinstaller.R; +import com.android.permissioncontroller.R; import com.android.packageinstaller.permission.ui.ConfirmActionDialogFragment .OnActionConfirmedListener; import com.android.packageinstaller.permission.ui.handheld.ReviewPermissionsFragment; diff --git a/src/com/android/packageinstaller/permission/ui/auto/AppPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/auto/AppPermissionsFragment.java index 9bc75fc4e..7ad0b38d8 100644 --- a/src/com/android/packageinstaller/permission/ui/auto/AppPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/auto/AppPermissionsFragment.java @@ -37,7 +37,7 @@ import androidx.car.widget.ListItemProvider; import androidx.car.widget.PagedListView; import androidx.car.widget.TextListItem; -import com.android.packageinstaller.R; +import com.android.permissioncontroller.R; import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.model.AppPermissions; import com.android.packageinstaller.permission.utils.Utils; diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AllAppPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AllAppPermissionsFragment.java index 1d8e5adfc..6bb83e22d 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AllAppPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AllAppPermissionsFragment.java @@ -40,7 +40,7 @@ import android.util.Log; import android.view.MenuItem; import android.widget.Switch; -import com.android.packageinstaller.R; +import com.android.permissioncontroller.R; import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.model.Permission; import com.android.packageinstaller.permission.utils.ArrayUtils; diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java index 917f238b8..f1a6aac4b 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java @@ -40,7 +40,7 @@ import android.view.MenuItem; import android.view.View; import android.widget.Toast; -import com.android.packageinstaller.R; +import com.android.permissioncontroller.R; import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.model.AppPermissions; import com.android.packageinstaller.permission.utils.SafetyNetLogger; diff --git a/src/com/android/packageinstaller/permission/ui/handheld/GrantPermissionsViewHandlerImpl.java b/src/com/android/packageinstaller/permission/ui/handheld/GrantPermissionsViewHandlerImpl.java index a9e5fc7f3..5d669af38 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/GrantPermissionsViewHandlerImpl.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/GrantPermissionsViewHandlerImpl.java @@ -44,7 +44,7 @@ import android.widget.RadioGroup; import android.widget.Space; import android.widget.TextView; -import com.android.packageinstaller.R; +import com.android.permissioncontroller.R; import com.android.packageinstaller.permission.ui.ButtonBarLayout; import com.android.packageinstaller.permission.ui.GrantPermissionsViewHandler; import com.android.packageinstaller.permission.ui.ManagePermissionsActivity; diff --git a/src/com/android/packageinstaller/permission/ui/handheld/ManageCustomPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/ManageCustomPermissionsFragment.java index 4f740e2c0..ffd0829f6 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/ManageCustomPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/ManageCustomPermissionsFragment.java @@ -26,7 +26,7 @@ public class ManageCustomPermissionsFragment extends ManagePermissionsFragment { public void onStart() { super.onStart(); - getActivity().setTitle(com.android.packageinstaller.R.string.additional_permissions); + getActivity().setTitle(com.android.permissioncontroller.R.string.additional_permissions); } @Override diff --git a/src/com/android/packageinstaller/permission/ui/handheld/ManagePermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/ManagePermissionsFragment.java index e50a1d89f..e838fdd7d 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/ManagePermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/ManagePermissionsFragment.java @@ -25,7 +25,7 @@ import android.preference.PreferenceScreen; import android.util.ArraySet; import android.util.Log; -import com.android.packageinstaller.R; +import com.android.permissioncontroller.R; import com.android.packageinstaller.permission.model.PermissionApps.PmCache; import com.android.packageinstaller.permission.model.PermissionGroup; import com.android.packageinstaller.permission.model.PermissionGroups; diff --git a/src/com/android/packageinstaller/permission/ui/handheld/ManageStandardPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/ManageStandardPermissionsFragment.java index 075ab3ce6..c5b9a9836 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/ManageStandardPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/ManageStandardPermissionsFragment.java @@ -20,7 +20,7 @@ import android.preference.Preference; import android.preference.PreferenceScreen; import android.view.MenuItem; -import com.android.packageinstaller.R; +import com.android.permissioncontroller.R; import com.android.packageinstaller.permission.model.PermissionGroup; import com.android.packageinstaller.permission.utils.Utils; @@ -43,7 +43,7 @@ public final class ManageStandardPermissionsFragment extends ManagePermissionsFr public void onStart() { super.onStart(); - getActivity().setTitle(com.android.packageinstaller.R.string.app_permissions); + getActivity().setTitle(com.android.permissioncontroller.R.string.app_permissions); } diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java index b2a37ac53..cde04bfaf 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java @@ -32,7 +32,7 @@ import android.view.MenuItem; import android.view.View; import com.android.packageinstaller.DeviceUtils; -import com.android.packageinstaller.R; +import com.android.permissioncontroller.R; import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.model.PermissionApps; import com.android.packageinstaller.permission.model.PermissionApps.Callback; diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionPreference.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionPreference.java index 0641778d6..63a37d018 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionPreference.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionPreference.java @@ -34,7 +34,7 @@ import android.widget.Switch; import androidx.annotation.IntDef; -import com.android.packageinstaller.R; +import com.android.permissioncontroller.R; import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.model.Permission; import com.android.packageinstaller.permission.utils.LocationUtils; diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionsFrameFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionsFrameFragment.java index e7f63b238..ba6bf49ef 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionsFrameFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionsFrameFragment.java @@ -26,7 +26,7 @@ import android.view.animation.Animation.AnimationListener; import android.view.animation.AnimationUtils; import android.widget.ListView; import android.widget.TextView; -import com.android.packageinstaller.R; +import com.android.permissioncontroller.R; public abstract class PermissionsFrameFragment extends PreferenceFragment { private ViewGroup mPreferencesContainer; diff --git a/src/com/android/packageinstaller/permission/ui/handheld/ReviewPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/ReviewPermissionsFragment.java index 83fef0dbc..892d2efd2 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/ReviewPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/ReviewPermissionsFragment.java @@ -40,7 +40,7 @@ import androidx.preference.PreferenceScreen; import androidx.preference.SwitchPreference; import androidx.preference.TwoStatePreference; -import com.android.packageinstaller.R; +import com.android.permissioncontroller.R; import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.model.AppPermissions; import com.android.packageinstaller.permission.model.Permission; diff --git a/src/com/android/packageinstaller/permission/ui/handheld/SettingsWithHeader.java b/src/com/android/packageinstaller/permission/ui/handheld/SettingsWithHeader.java index d57757964..6d8f076d6 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/SettingsWithHeader.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/SettingsWithHeader.java @@ -27,7 +27,7 @@ import android.widget.ImageView; import android.widget.TextView; import com.android.packageinstaller.DeviceUtils; -import com.android.packageinstaller.R; +import com.android.permissioncontroller.R; public abstract class SettingsWithHeader extends PermissionsFrameFragment implements OnClickListener { diff --git a/src/com/android/packageinstaller/permission/ui/television/AllAppPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/television/AllAppPermissionsFragment.java index e56a1f7db..577197883 100644 --- a/src/com/android/packageinstaller/permission/ui/television/AllAppPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/television/AllAppPermissionsFragment.java @@ -43,7 +43,7 @@ import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceGroup; import androidx.preference.SwitchPreference; -import com.android.packageinstaller.R; +import com.android.permissioncontroller.R; import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.model.AppPermissions; import com.android.packageinstaller.permission.utils.Utils; diff --git a/src/com/android/packageinstaller/permission/ui/television/AppPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/television/AppPermissionsFragment.java index 442ee9287..c57b4ba48 100644 --- a/src/com/android/packageinstaller/permission/ui/television/AppPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/television/AppPermissionsFragment.java @@ -43,7 +43,7 @@ import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceViewHolder; import androidx.preference.SwitchPreference; -import com.android.packageinstaller.R; +import com.android.permissioncontroller.R; import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.model.AppPermissions; import com.android.packageinstaller.permission.ui.ReviewPermissionsActivity; diff --git a/src/com/android/packageinstaller/permission/ui/television/GrantPermissionsViewHandlerImpl.java b/src/com/android/packageinstaller/permission/ui/television/GrantPermissionsViewHandlerImpl.java index c71835734..81d2cb339 100644 --- a/src/com/android/packageinstaller/permission/ui/television/GrantPermissionsViewHandlerImpl.java +++ b/src/com/android/packageinstaller/permission/ui/television/GrantPermissionsViewHandlerImpl.java @@ -14,7 +14,7 @@ import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; -import com.android.packageinstaller.R; +import com.android.permissioncontroller.R; import com.android.packageinstaller.permission.ui.GrantPermissionsViewHandler; /** diff --git a/src/com/android/packageinstaller/permission/ui/television/ManagePermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/television/ManagePermissionsFragment.java index 19f01d0f9..f962f283e 100644 --- a/src/com/android/packageinstaller/permission/ui/television/ManagePermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/television/ManagePermissionsFragment.java @@ -30,7 +30,7 @@ import android.util.Log; import android.view.MenuItem; import android.view.View; -import com.android.packageinstaller.R; +import com.android.permissioncontroller.R; import com.android.packageinstaller.permission.model.PermissionApps.PmCache; import com.android.packageinstaller.permission.model.PermissionGroup; import com.android.packageinstaller.permission.model.PermissionGroups; diff --git a/src/com/android/packageinstaller/permission/ui/television/PermissionAppsFragment.java b/src/com/android/packageinstaller/permission/ui/television/PermissionAppsFragment.java index 6a0a9e7c7..d659f4799 100644 --- a/src/com/android/packageinstaller/permission/ui/television/PermissionAppsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/television/PermissionAppsFragment.java @@ -38,7 +38,7 @@ import androidx.preference.PreferenceScreen; import androidx.preference.SwitchPreference; import com.android.packageinstaller.DeviceUtils; -import com.android.packageinstaller.R; +import com.android.permissioncontroller.R; import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.model.PermissionApps; import com.android.packageinstaller.permission.model.PermissionApps.Callback; diff --git a/src/com/android/packageinstaller/permission/ui/television/PermissionsFrameFragment.java b/src/com/android/packageinstaller/permission/ui/television/PermissionsFrameFragment.java index af4593ae0..69659ec61 100644 --- a/src/com/android/packageinstaller/permission/ui/television/PermissionsFrameFragment.java +++ b/src/com/android/packageinstaller/permission/ui/television/PermissionsFrameFragment.java @@ -30,7 +30,7 @@ import android.view.animation.Animation.AnimationListener; import android.view.animation.AnimationUtils; import android.widget.TextView; -import com.android.packageinstaller.R; +import com.android.permissioncontroller.R; public abstract class PermissionsFrameFragment extends PreferenceFragment { diff --git a/src/com/android/packageinstaller/permission/ui/television/SettingsWithHeader.java b/src/com/android/packageinstaller/permission/ui/television/SettingsWithHeader.java index 06f7c1426..5efcee628 100644 --- a/src/com/android/packageinstaller/permission/ui/television/SettingsWithHeader.java +++ b/src/com/android/packageinstaller/permission/ui/television/SettingsWithHeader.java @@ -26,7 +26,7 @@ import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import com.android.packageinstaller.DeviceUtils; -import com.android.packageinstaller.R; +import com.android.permissioncontroller.R; public abstract class SettingsWithHeader extends PermissionsFrameFragment implements OnClickListener { diff --git a/src/com/android/packageinstaller/permission/ui/wear/AppPermissionsFragmentWear.java b/src/com/android/packageinstaller/permission/ui/wear/AppPermissionsFragmentWear.java index 20495aac2..3de638698 100644 --- a/src/com/android/packageinstaller/permission/ui/wear/AppPermissionsFragmentWear.java +++ b/src/com/android/packageinstaller/permission/ui/wear/AppPermissionsFragmentWear.java @@ -36,7 +36,7 @@ import android.widget.Toast; import androidx.wear.ble.view.WearableDialogHelper; -import com.android.packageinstaller.R; +import com.android.permissioncontroller.R; import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.model.AppPermissions; import com.android.packageinstaller.permission.model.Permission; diff --git a/src/com/android/packageinstaller/permission/ui/wear/ReviewPermissionsWearFragment.java b/src/com/android/packageinstaller/permission/ui/wear/ReviewPermissionsWearFragment.java index 5aa7cafec..64ef25ed3 100644 --- a/src/com/android/packageinstaller/permission/ui/wear/ReviewPermissionsWearFragment.java +++ b/src/com/android/packageinstaller/permission/ui/wear/ReviewPermissionsWearFragment.java @@ -37,7 +37,7 @@ import androidx.preference.SwitchPreference; import androidx.preference.TwoStatePreference; import androidx.wear.ble.view.WearableDialogHelper; -import com.android.packageinstaller.R; +import com.android.permissioncontroller.R; import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.model.AppPermissions; import com.android.packageinstaller.permission.utils.Utils; diff --git a/src/com/android/packageinstaller/permission/utils/LocationUtils.java b/src/com/android/packageinstaller/permission/utils/LocationUtils.java index 0296ae80a..e7af37880 100644 --- a/src/com/android/packageinstaller/permission/utils/LocationUtils.java +++ b/src/com/android/packageinstaller/permission/utils/LocationUtils.java @@ -28,7 +28,7 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.provider.Settings; -import com.android.packageinstaller.R; +import com.android.permissioncontroller.R; import java.util.ArrayList; diff --git a/src/com/android/packageinstaller/permission/utils/Utils.java b/src/com/android/packageinstaller/permission/utils/Utils.java index d7ee219b0..6fc17048c 100644 --- a/src/com/android/packageinstaller/permission/utils/Utils.java +++ b/src/com/android/packageinstaller/permission/utils/Utils.java @@ -31,7 +31,7 @@ import android.util.ArraySet; import android.util.Log; import android.util.TypedValue; -import com.android.packageinstaller.R; +import com.android.permissioncontroller.R; import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.model.AppPermissions; import com.android.packageinstaller.permission.model.PermissionApps.PermissionApp; diff --git a/src/com/android/packageinstaller/television/ErrorFragment.java b/src/com/android/packageinstaller/television/ErrorFragment.java deleted file mode 100644 index f00f68445..000000000 --- a/src/com/android/packageinstaller/television/ErrorFragment.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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 - */ - -package com.android.packageinstaller.television; - -import android.app.Activity; -import android.os.Bundle; -import androidx.leanback.app.GuidedStepFragment; -import androidx.leanback.widget.GuidanceStylist; -import androidx.leanback.widget.GuidedAction; - -import com.android.packageinstaller.R; -import com.android.packageinstaller.UninstallerActivity; - -import java.util.List; - -public class ErrorFragment extends GuidedStepFragment { - public static final String TITLE = "com.android.packageinstaller.arg.title"; - public static final String TEXT = "com.android.packageinstaller.arg.text"; - - @Override - public int onProvideTheme() { - return R.style.Theme_Leanback_GuidedStep; - } - - @Override - public GuidanceStylist.Guidance onCreateGuidance(Bundle savedInstanceState) { - return new GuidanceStylist.Guidance( - getString(getArguments().getInt(TITLE)), - getString(getArguments().getInt(TEXT)), - null, - null); - } - - @Override - public void onCreateActions(List actions, Bundle savedInstanceState) { - actions.add(new GuidedAction.Builder(getContext()) - .clickAction(GuidedAction.ACTION_ID_OK) - .build()); - } - - @Override - public void onGuidedActionClicked(GuidedAction action) { - if (isAdded()) { - if (getActivity() instanceof UninstallerActivity) { - ((UninstallerActivity) getActivity()).dispatchAborted(); - } - - getActivity().setResult(Activity.RESULT_FIRST_USER); - getActivity().finish(); - } - } -} diff --git a/src/com/android/packageinstaller/television/UninstallAlertFragment.java b/src/com/android/packageinstaller/television/UninstallAlertFragment.java deleted file mode 100644 index 828e5dbcf..000000000 --- a/src/com/android/packageinstaller/television/UninstallAlertFragment.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * 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 - */ - -package com.android.packageinstaller.television; - -import android.app.Activity; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.content.pm.UserInfo; -import android.os.Bundle; -import android.os.UserManager; -import androidx.leanback.app.GuidedStepFragment; -import androidx.leanback.widget.GuidanceStylist; -import androidx.leanback.widget.GuidedAction; - -import com.android.packageinstaller.R; -import com.android.packageinstaller.UninstallerActivity; - -import java.util.List; - -public class UninstallAlertFragment extends GuidedStepFragment { - @Override - public int onProvideTheme() { - return R.style.Theme_Leanback_GuidedStep; - } - - @Override - public GuidanceStylist.Guidance onCreateGuidance(Bundle savedInstanceState) { - final PackageManager pm = getActivity().getPackageManager(); - final UninstallerActivity.DialogInfo dialogInfo = - ((UninstallerActivity) getActivity()).getDialogInfo(); - final CharSequence appLabel = dialogInfo.appInfo.loadSafeLabel(pm); - - StringBuilder messageBuilder = new StringBuilder(); - - // If the Activity label differs from the App label, then make sure the user - // knows the Activity belongs to the App being uninstalled. - if (dialogInfo.activityInfo != null) { - final CharSequence activityLabel = dialogInfo.activityInfo.loadSafeLabel(pm); - if (!activityLabel.equals(appLabel)) { - messageBuilder.append( - getString(R.string.uninstall_activity_text, activityLabel)); - messageBuilder.append(" ").append(appLabel).append(".\n\n"); - } - } - - final boolean isUpdate = - ((dialogInfo.appInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0); - UserManager userManager = UserManager.get(getActivity()); - if (isUpdate) { - if (isSingleUser(userManager)) { - messageBuilder.append(getString(R.string.uninstall_update_text)); - } else { - messageBuilder.append(getString(R.string.uninstall_update_text_multiuser)); - } - } else { - if (dialogInfo.allUsers && !isSingleUser(userManager)) { - messageBuilder.append(getString(R.string.uninstall_application_text_all_users)); - } else if (!dialogInfo.user.equals(android.os.Process.myUserHandle())) { - UserInfo userInfo = userManager.getUserInfo(dialogInfo.user.getIdentifier()); - messageBuilder.append( - getString(R.string.uninstall_application_text_user, userInfo.name)); - } else { - messageBuilder.append(getString(R.string.uninstall_application_text)); - } - } - - return new GuidanceStylist.Guidance( - appLabel.toString(), - messageBuilder.toString(), - null, - dialogInfo.appInfo.loadIcon(pm)); - } - - @Override - public void onCreateActions(List actions, Bundle savedInstanceState) { - actions.add(new GuidedAction.Builder(getContext()) - .clickAction(GuidedAction.ACTION_ID_OK) - .build()); - actions.add(new GuidedAction.Builder(getContext()) - .clickAction(GuidedAction.ACTION_ID_CANCEL) - .build()); - } - - @Override - public void onGuidedActionClicked(GuidedAction action) { - if (isAdded()) { - if (action.getId() == GuidedAction.ACTION_ID_OK) { - ((UninstallerActivity) getActivity()).startUninstallProgress(); - getActivity().finish(); - } else { - ((UninstallerActivity) getActivity()).dispatchAborted(); - getActivity().setResult(Activity.RESULT_FIRST_USER); - getActivity().finish(); - } - } - } - - /** - * Returns whether there is only one user on this device, not including - * the system-only user. - */ - private boolean isSingleUser(UserManager userManager) { - final int userCount = userManager.getUserCount(); - return userCount == 1 - || (UserManager.isSplitSystemUser() && userCount == 2); - } -} diff --git a/src/com/android/packageinstaller/television/UninstallAppProgress.java b/src/com/android/packageinstaller/television/UninstallAppProgress.java deleted file mode 100755 index a4f217c4a..000000000 --- a/src/com/android/packageinstaller/television/UninstallAppProgress.java +++ /dev/null @@ -1,377 +0,0 @@ -/* -** -** Copyright 2007, 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.packageinstaller.television; - -import android.app.Activity; -import android.app.admin.IDevicePolicyManager; -import android.content.Context; -import android.content.Intent; -import android.content.pm.ApplicationInfo; -import android.content.pm.IPackageDeleteObserver; -import android.content.pm.IPackageDeleteObserver2; -import android.content.pm.IPackageManager; -import android.content.pm.PackageInstaller; -import android.content.pm.PackageManager; -import android.content.pm.UserInfo; -import android.graphics.Color; -import android.graphics.drawable.ColorDrawable; -import android.os.Bundle; -import android.os.Handler; -import android.os.IBinder; -import android.os.Message; -import android.os.RemoteException; -import android.os.ServiceManager; -import android.os.UserHandle; -import android.os.UserManager; -import android.util.Log; -import android.util.TypedValue; -import android.view.KeyEvent; -import android.widget.Toast; - -import com.android.packageinstaller.PackageUtil; -import com.android.packageinstaller.R; - -import java.lang.ref.WeakReference; -import java.util.List; - -/** - * This activity corresponds to a download progress screen that is displayed - * when an application is uninstalled. The result of the application uninstall - * is indicated in the result code that gets set to 0 or 1. The application gets launched - * by an intent with the intent's class name explicitly set to UninstallAppProgress and expects - * the application object of the application to uninstall. - */ -public class UninstallAppProgress extends Activity { - private static final String TAG = "UninstallAppProgress"; - - private static final String FRAGMENT_TAG = "progress_fragment"; - - private ApplicationInfo mAppInfo; - private boolean mAllUsers; - private IBinder mCallback; - - private volatile int mResultCode = -1; - - /** - * If initView was called. We delay this call to not have to call it at all if the uninstall is - * quick - */ - private boolean mIsViewInitialized; - - /** Amount of time to wait until we show the UI */ - private static final int QUICK_INSTALL_DELAY_MILLIS = 500; - - private static final int UNINSTALL_COMPLETE = 1; - private static final int UNINSTALL_IS_SLOW = 2; - - private Handler mHandler = new MessageHandler(this); - - private static class MessageHandler extends Handler { - private final WeakReference mActivity; - - public MessageHandler(UninstallAppProgress activity) { - mActivity = new WeakReference<>(activity); - } - - @Override - public void handleMessage(Message msg) { - UninstallAppProgress activity = mActivity.get(); - if (activity != null) { - activity.handleMessage(msg); - } - } - } - - private void handleMessage(Message msg) { - if (isFinishing() || isDestroyed()) { - return; - } - - switch (msg.what) { - case UNINSTALL_IS_SLOW: - initView(); - break; - case UNINSTALL_COMPLETE: - mHandler.removeMessages(UNINSTALL_IS_SLOW); - - if (msg.arg1 != PackageManager.DELETE_SUCCEEDED) { - initView(); - } - - mResultCode = msg.arg1; - final String packageName = (String) msg.obj; - - if (mCallback != null) { - final IPackageDeleteObserver2 observer = IPackageDeleteObserver2.Stub - .asInterface(mCallback); - try { - observer.onPackageDeleted(mAppInfo.packageName, mResultCode, - packageName); - } catch (RemoteException ignored) { - } - finish(); - return; - } - - if (getIntent().getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false)) { - Intent result = new Intent(); - result.putExtra(Intent.EXTRA_INSTALL_RESULT, mResultCode); - setResult(mResultCode == PackageManager.DELETE_SUCCEEDED - ? Activity.RESULT_OK : Activity.RESULT_FIRST_USER, - result); - finish(); - return; - } - - // Update the status text - final String statusText; - switch (msg.arg1) { - case PackageManager.DELETE_SUCCEEDED: - statusText = getString(R.string.uninstall_done); - // Show a Toast and finish the activity - Context ctx = getBaseContext(); - Toast.makeText(ctx, statusText, Toast.LENGTH_LONG).show(); - setResultAndFinish(); - return; - case PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER: { - UserManager userManager = - (UserManager) getSystemService(Context.USER_SERVICE); - IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface( - ServiceManager.getService(Context.DEVICE_POLICY_SERVICE)); - // Find out if the package is an active admin for some non-current user. - int myUserId = UserHandle.myUserId(); - UserInfo otherBlockingUser = null; - for (UserInfo user : userManager.getUsers()) { - // We only catch the case when the user in question is neither the - // current user nor its profile. - if (isProfileOfOrSame(userManager, myUserId, user.id)) continue; - - try { - if (dpm.packageHasActiveAdmins(packageName, user.id)) { - otherBlockingUser = user; - break; - } - } catch (RemoteException e) { - Log.e(TAG, "Failed to talk to package manager", e); - } - } - if (otherBlockingUser == null) { - Log.d(TAG, "Uninstall failed because " + packageName - + " is a device admin"); - getProgressFragment().setDeviceManagerButtonVisible(true); - statusText = getString( - R.string.uninstall_failed_device_policy_manager); - } else { - Log.d(TAG, "Uninstall failed because " + packageName - + " is a device admin of user " + otherBlockingUser); - getProgressFragment().setDeviceManagerButtonVisible(false); - statusText = String.format( - getString(R.string.uninstall_failed_device_policy_manager_of_user), - otherBlockingUser.name); - } - break; - } - case PackageManager.DELETE_FAILED_OWNER_BLOCKED: { - UserManager userManager = - (UserManager) getSystemService(Context.USER_SERVICE); - IPackageManager packageManager = IPackageManager.Stub.asInterface( - ServiceManager.getService("package")); - List users = userManager.getUsers(); - int blockingUserId = UserHandle.USER_NULL; - for (int i = 0; i < users.size(); ++i) { - final UserInfo user = users.get(i); - try { - if (packageManager.getBlockUninstallForUser(packageName, - user.id)) { - blockingUserId = user.id; - break; - } - } catch (RemoteException e) { - // Shouldn't happen. - Log.e(TAG, "Failed to talk to package manager", e); - } - } - int myUserId = UserHandle.myUserId(); - if (isProfileOfOrSame(userManager, myUserId, blockingUserId)) { - getProgressFragment().setDeviceManagerButtonVisible(true); - } else { - getProgressFragment().setDeviceManagerButtonVisible(false); - getProgressFragment().setUsersButtonVisible(true); - } - // TODO: b/25442806 - if (blockingUserId == UserHandle.USER_SYSTEM) { - statusText = getString(R.string.uninstall_blocked_device_owner); - } else if (blockingUserId == UserHandle.USER_NULL) { - Log.d(TAG, "Uninstall failed for " + packageName + " with code " - + msg.arg1 + " no blocking user"); - statusText = getString(R.string.uninstall_failed); - } else { - statusText = mAllUsers - ? getString(R.string.uninstall_all_blocked_profile_owner) : - getString(R.string.uninstall_blocked_profile_owner); - } - break; - } - default: - Log.d(TAG, "Uninstall failed for " + packageName + " with code " - + msg.arg1); - statusText = getString(R.string.uninstall_failed); - break; - } - getProgressFragment().showCompletion(statusText); - break; - default: - break; - } - } - - private boolean isProfileOfOrSame(UserManager userManager, int userId, int profileId) { - if (userId == profileId) { - return true; - } - UserInfo parentUser = userManager.getProfileParent(profileId); - return parentUser != null && parentUser.id == userId; - } - - @Override - public void onCreate(Bundle icicle) { - super.onCreate(icicle); - - Intent intent = getIntent(); - mAppInfo = intent.getParcelableExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO); - mCallback = intent.getIBinderExtra(PackageInstaller.EXTRA_CALLBACK); - - // This currently does not support going through a onDestroy->onCreate cycle. Hence if that - // happened, just fail the operation for mysterious reasons. - if (icicle != null) { - mResultCode = PackageManager.DELETE_FAILED_INTERNAL_ERROR; - - if (mCallback != null) { - final IPackageDeleteObserver2 observer = IPackageDeleteObserver2.Stub - .asInterface(mCallback); - try { - observer.onPackageDeleted(mAppInfo.packageName, mResultCode, null); - } catch (RemoteException ignored) { - } - finish(); - } else { - setResultAndFinish(); - } - - return; - } - - mAllUsers = intent.getBooleanExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, false); - UserHandle user = intent.getParcelableExtra(Intent.EXTRA_USER); - if (user == null) { - user = android.os.Process.myUserHandle(); - } - - PackageDeleteObserver observer = new PackageDeleteObserver(); - - // Make window transparent until initView is called. In many cases we can avoid showing the - // UI at all as the app is uninstalled very quickly. If we show the UI and instantly remove - // it, it just looks like a flicker. - getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); - getWindow().setStatusBarColor(Color.TRANSPARENT); - getWindow().setNavigationBarColor(Color.TRANSPARENT); - - try { - getPackageManager().deletePackageAsUser(mAppInfo.packageName, observer, - mAllUsers ? PackageManager.DELETE_ALL_USERS : 0, user.getIdentifier()); - } catch (IllegalArgumentException e) { - // Couldn't find the package, no need to call uninstall. - Log.w(TAG, "Could not find package, not deleting " + mAppInfo.packageName, e); - } - - mHandler.sendMessageDelayed(mHandler.obtainMessage(UNINSTALL_IS_SLOW), - QUICK_INSTALL_DELAY_MILLIS); - } - - public ApplicationInfo getAppInfo() { - return mAppInfo; - } - - private class PackageDeleteObserver extends IPackageDeleteObserver.Stub { - public void packageDeleted(String packageName, int returnCode) { - Message msg = mHandler.obtainMessage(UNINSTALL_COMPLETE); - msg.arg1 = returnCode; - msg.obj = packageName; - mHandler.sendMessage(msg); - } - } - - public void setResultAndFinish() { - setResult(mResultCode); - finish(); - } - - private void initView() { - if (mIsViewInitialized) { - return; - } - mIsViewInitialized = true; - - // We set the window background to translucent in constructor, revert this - TypedValue attribute = new TypedValue(); - getTheme().resolveAttribute(android.R.attr.windowBackground, attribute, true); - if (attribute.type >= TypedValue.TYPE_FIRST_COLOR_INT && - attribute.type <= TypedValue.TYPE_LAST_COLOR_INT) { - getWindow().setBackgroundDrawable(new ColorDrawable(attribute.data)); - } else { - getWindow().setBackgroundDrawable(getResources().getDrawable(attribute.resourceId, - getTheme())); - } - - getTheme().resolveAttribute(android.R.attr.navigationBarColor, attribute, true); - getWindow().setNavigationBarColor(attribute.data); - - getTheme().resolveAttribute(android.R.attr.statusBarColor, attribute, true); - getWindow().setStatusBarColor(attribute.data); - - boolean isUpdate = ((mAppInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0); - setTitle(isUpdate ? R.string.uninstall_update_title : R.string.uninstall_application_title); - - getFragmentManager().beginTransaction() - .add(android.R.id.content, new UninstallAppProgressFragment(), FRAGMENT_TAG) - .commitNowAllowingStateLoss(); - } - - @Override - public boolean dispatchKeyEvent(KeyEvent ev) { - if (ev.getKeyCode() == KeyEvent.KEYCODE_BACK) { - if (mResultCode == -1) { - // Ignore back key when installation is in progress - return true; - } else { - // If installation is done, just set the result code - setResult(mResultCode); - } - } - return super.dispatchKeyEvent(ev); - } - - private ProgressFragment getProgressFragment() { - return (ProgressFragment) getFragmentManager().findFragmentByTag(FRAGMENT_TAG); - } - - public interface ProgressFragment { - void setUsersButtonVisible(boolean visible); - void setDeviceManagerButtonVisible(boolean visible); - void showCompletion(CharSequence statusText); - } -} diff --git a/src/com/android/packageinstaller/television/UninstallAppProgressFragment.java b/src/com/android/packageinstaller/television/UninstallAppProgressFragment.java deleted file mode 100644 index 7402a7dae..000000000 --- a/src/com/android/packageinstaller/television/UninstallAppProgressFragment.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * 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 - */ - -package com.android.packageinstaller.television; - -import android.app.Fragment; -import android.content.Intent; -import android.os.Bundle; -import android.provider.Settings; -import androidx.annotation.Nullable; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.TextView; - -import com.android.packageinstaller.PackageUtil; -import com.android.packageinstaller.R; - -public class UninstallAppProgressFragment extends Fragment implements View.OnClickListener, - UninstallAppProgress.ProgressFragment { - private static final String TAG = "UninstallAppProgressF"; // full class name is too long - - private Button mOkButton; - private Button mDeviceManagerButton; - private Button mUsersButton; - - @Override - public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, - Bundle savedInstanceState) { - final View root = inflater.inflate(R.layout.uninstall_progress, container, false); - // Initialize views - View snippetView = root.findViewById(R.id.app_snippet); - PackageUtil.initSnippetForInstalledApp(getContext(), - ((UninstallAppProgress)getActivity()).getAppInfo(), snippetView); - mDeviceManagerButton = (Button) root.findViewById(R.id.device_manager_button); - mUsersButton = (Button) root.findViewById(R.id.users_button); - mDeviceManagerButton.setVisibility(View.GONE); - mDeviceManagerButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Intent intent = new Intent(); - intent.setClassName("com.android.settings", - "com.android.settings.Settings$DeviceAdminSettingsActivity"); - intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_NEW_TASK); - startActivity(intent); - getActivity().finish(); - } - }); - mUsersButton.setVisibility(View.GONE); - mUsersButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Intent intent = new Intent(Settings.ACTION_USER_SETTINGS); - intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_NEW_TASK); - startActivity(intent); - getActivity().finish(); - } - }); - // Hide button till progress is being displayed - mOkButton = (Button) root.findViewById(R.id.ok_button); - mOkButton.setOnClickListener(this); - - return root; - } - - public void onClick(View v) { - final UninstallAppProgress activity = (UninstallAppProgress) getActivity(); - if(v == mOkButton && activity != null) { - Log.i(TAG, "Finished uninstalling pkg: " + - activity.getAppInfo().packageName); - activity.setResultAndFinish(); - } - } - - @Override - public void setUsersButtonVisible(boolean visible) { - mUsersButton.setVisibility(visible ? View.VISIBLE : View.GONE); - } - - @Override - public void setDeviceManagerButtonVisible(boolean visible) { - mDeviceManagerButton.setVisibility(visible ? View.VISIBLE : View.GONE); - } - - @Override - public void showCompletion(CharSequence statusText) { - final View root = getView(); - root.findViewById(R.id.progress_view).setVisibility(View.GONE); - root.findViewById(R.id.status_view).setVisibility(View.VISIBLE); - ((TextView) root.findViewById(R.id.status_text)).setText(statusText); - root.findViewById(R.id.ok_panel).setVisibility(View.VISIBLE); - } -} diff --git a/src/com/android/packageinstaller/wear/InstallTask.java b/src/com/android/packageinstaller/wear/InstallTask.java deleted file mode 100644 index 53a460dc1..000000000 --- a/src/com/android/packageinstaller/wear/InstallTask.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * 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 - */ - -package com.android.packageinstaller.wear; - -import android.content.Context; -import android.content.IntentSender; -import android.content.pm.PackageInstaller; -import android.os.Looper; -import android.os.ParcelFileDescriptor; -import android.text.TextUtils; -import android.util.Log; - -import java.io.Closeable; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -/** - * Task that installs an APK. This must not be called on the main thread. - * This code is based off the Finsky/Wearsky implementation - */ -public class InstallTask { - private static final String TAG = "InstallTask"; - - private static final int DEFAULT_BUFFER_SIZE = 8192; - - private final Context mContext; - private String mPackageName; - private ParcelFileDescriptor mParcelFileDescriptor; - private PackageInstallerImpl.InstallListener mCallback; - private PackageInstaller.Session mSession; - private IntentSender mCommitCallback; - - private Exception mException = null; - private int mErrorCode = 0; - private String mErrorDesc = null; - - public InstallTask(Context context, String packageName, - ParcelFileDescriptor parcelFileDescriptor, - PackageInstallerImpl.InstallListener callback, PackageInstaller.Session session, - IntentSender commitCallback) { - mContext = context; - mPackageName = packageName; - mParcelFileDescriptor = parcelFileDescriptor; - mCallback = callback; - mSession = session; - mCommitCallback = commitCallback; - } - - public boolean isError() { - return mErrorCode != InstallerConstants.STATUS_SUCCESS || !TextUtils.isEmpty(mErrorDesc); - } - - public void execute() { - if (Looper.myLooper() == Looper.getMainLooper()) { - throw new IllegalStateException("This method cannot be called from the UI thread."); - } - - OutputStream sessionStream = null; - try { - sessionStream = mSession.openWrite(mPackageName, 0, -1); - - // 2b: Stream the asset to the installer. Note: - // Note: writeToOutputStreamFromAsset() always safely closes the input stream - writeToOutputStreamFromAsset(sessionStream); - mSession.fsync(sessionStream); - } catch (Exception e) { - mException = e; - mErrorCode = InstallerConstants.ERROR_INSTALL_COPY_STREAM; - mErrorDesc = "Could not write to stream"; - } finally { - if (sessionStream != null) { - // 2c: close output stream - try { - sessionStream.close(); - } catch (Exception e) { - // Ignore otherwise - if (mException == null) { - mException = e; - mErrorCode = InstallerConstants.ERROR_INSTALL_CLOSE_STREAM; - mErrorDesc = "Could not close session stream"; - } - } - } - } - - if (mErrorCode != InstallerConstants.STATUS_SUCCESS) { - // An error occurred, we're done - Log.e(TAG, "Exception while installing " + mPackageName + ": " + mErrorCode + ", " - + mErrorDesc + ", " + mException); - mSession.close(); - mCallback.installFailed(mErrorCode, "[" + mPackageName + "]" + mErrorDesc); - } else { - // 3. Commit the session (this actually installs it.) Session map - // will be cleaned up in the callback. - mCallback.installBeginning(); - mSession.commit(mCommitCallback); - mSession.close(); - } - } - - /** - * {@code PackageInstaller} works with streams. Get the {@code FileDescriptor} - * corresponding to the {@code Asset} and then write the contents into an - * {@code OutputStream} that is passed in. - *
- * The {@code FileDescriptor} is closed but the {@code OutputStream} is not closed. - */ - private boolean writeToOutputStreamFromAsset(OutputStream outputStream) { - if (outputStream == null) { - mErrorCode = InstallerConstants.ERROR_INSTALL_COPY_STREAM_EXCEPTION; - mErrorDesc = "Got a null OutputStream."; - return false; - } - - if (mParcelFileDescriptor == null || mParcelFileDescriptor.getFileDescriptor() == null) { - mErrorCode = InstallerConstants.ERROR_COULD_NOT_GET_FD; - mErrorDesc = "Could not get FD"; - return false; - } - - InputStream inputStream = null; - try { - byte[] inputBuf = new byte[DEFAULT_BUFFER_SIZE]; - int bytesRead; - inputStream = new ParcelFileDescriptor.AutoCloseInputStream(mParcelFileDescriptor); - - while ((bytesRead = inputStream.read(inputBuf)) > -1) { - if (bytesRead > 0) { - outputStream.write(inputBuf, 0, bytesRead); - } - } - - outputStream.flush(); - } catch (IOException e) { - mErrorCode = InstallerConstants.ERROR_INSTALL_APK_COPY_FAILURE; - mErrorDesc = "Reading from Asset FD or writing to temp file failed: " + e; - return false; - } finally { - safeClose(inputStream); - } - - return true; - } - - /** - * Quietly close a closeable resource (e.g. a stream or file). The input may already - * be closed and it may even be null. - */ - public static void safeClose(Closeable resource) { - if (resource != null) { - try { - resource.close(); - } catch (IOException ioe) { - // Catch and discard the error - } - } - } -} \ No newline at end of file diff --git a/src/com/android/packageinstaller/wear/InstallerConstants.java b/src/com/android/packageinstaller/wear/InstallerConstants.java deleted file mode 100644 index 3daf3d831..000000000 --- a/src/com/android/packageinstaller/wear/InstallerConstants.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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 - */ - -package com.android.packageinstaller.wear; - -/** - * Constants for Installation / Uninstallation requests. - * Using the same values as Finsky/Wearsky code for consistency in user analytics of failures - */ -public class InstallerConstants { - /** Request succeeded */ - public static final int STATUS_SUCCESS = 0; - - /** - * The new PackageInstaller also returns a small set of less granular error codes, which - * we'll remap to the range -500 and below to keep away from existing installer codes - * (which run from -1 to -110). - */ - public final static int ERROR_PACKAGEINSTALLER_BASE = -500; - - public static final int ERROR_COULD_NOT_GET_FD = -603; - /** This node is not targeted by this request. */ - - /** The install did not complete because could not create PackageInstaller session */ - public final static int ERROR_INSTALL_CREATE_SESSION = -612; - /** The install did not complete because could not open PackageInstaller session */ - public final static int ERROR_INSTALL_OPEN_SESSION = -613; - /** The install did not complete because could not open PackageInstaller output stream */ - public final static int ERROR_INSTALL_OPEN_STREAM = -614; - /** The install did not complete because of an exception while streaming bytes */ - public final static int ERROR_INSTALL_COPY_STREAM_EXCEPTION = -615; - /** The install did not complete because of an unexpected exception from PackageInstaller */ - public final static int ERROR_INSTALL_SESSION_EXCEPTION = -616; - /** The install did not complete because of an unexpected userActionRequired callback */ - public final static int ERROR_INSTALL_USER_ACTION_REQUIRED = -617; - /** The install did not complete because of an unexpected broadcast (missing fields) */ - public final static int ERROR_INSTALL_MALFORMED_BROADCAST = -618; - /** The install did not complete because of an error while copying from downloaded file */ - public final static int ERROR_INSTALL_APK_COPY_FAILURE = -619; - /** The install did not complete because of an error while copying to the PackageInstaller - * output stream */ - public final static int ERROR_INSTALL_COPY_STREAM = -620; - /** The install did not complete because of an error while closing the PackageInstaller - * output stream */ - public final static int ERROR_INSTALL_CLOSE_STREAM = -621; -} \ No newline at end of file diff --git a/src/com/android/packageinstaller/wear/PackageInstallerFactory.java b/src/com/android/packageinstaller/wear/PackageInstallerFactory.java deleted file mode 100644 index bdc22cf0e..000000000 --- a/src/com/android/packageinstaller/wear/PackageInstallerFactory.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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 - */ - -package com.android.packageinstaller.wear; - -import android.content.Context; - -/** - * Factory that creates a Package Installer. - */ -public class PackageInstallerFactory { - private static PackageInstallerImpl sPackageInstaller; - - /** - * Return the PackageInstaller shared object. {@code init} should have already been called. - */ - public synchronized static PackageInstallerImpl getPackageInstaller(Context context) { - if (sPackageInstaller == null) { - sPackageInstaller = new PackageInstallerImpl(context); - } - return sPackageInstaller; - } -} \ No newline at end of file diff --git a/src/com/android/packageinstaller/wear/PackageInstallerImpl.java b/src/com/android/packageinstaller/wear/PackageInstallerImpl.java deleted file mode 100644 index bf4b03c56..000000000 --- a/src/com/android/packageinstaller/wear/PackageInstallerImpl.java +++ /dev/null @@ -1,325 +0,0 @@ -/* - * 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 - */ - -package com.android.packageinstaller.wear; - -import android.annotation.TargetApi; -import android.app.PendingIntent; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.IntentSender; -import android.content.pm.PackageInstaller; -import android.os.Build; -import android.os.ParcelFileDescriptor; -import android.util.Log; - -import java.io.IOException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Implementation of package manager installation using modern PackageInstaller api. - * - * Heavily copied from Wearsky/Finsky implementation - */ -@TargetApi(Build.VERSION_CODES.LOLLIPOP) -public class PackageInstallerImpl { - private static final String TAG = "PackageInstallerImpl"; - - /** Intent actions used for broadcasts from PackageInstaller back to the local receiver */ - private static final String ACTION_INSTALL_COMMIT = - "com.android.vending.INTENT_PACKAGE_INSTALL_COMMIT"; - - private final Context mContext; - private final PackageInstaller mPackageInstaller; - private final Map mSessionInfoMap; - private final Map mOpenSessionMap; - - public PackageInstallerImpl(Context context) { - mContext = context.getApplicationContext(); - mPackageInstaller = mContext.getPackageManager().getPackageInstaller(); - - // Capture a map of known sessions - // This list will be pruned a bit later (stale sessions will be canceled) - mSessionInfoMap = new HashMap(); - List mySessions = mPackageInstaller.getMySessions(); - for (int i = 0; i < mySessions.size(); i++) { - PackageInstaller.SessionInfo sessionInfo = mySessions.get(i); - String packageName = sessionInfo.getAppPackageName(); - PackageInstaller.SessionInfo oldInfo = mSessionInfoMap.put(packageName, sessionInfo); - - // Checking for old info is strictly for logging purposes - if (oldInfo != null) { - Log.w(TAG, "Multiple sessions for " + packageName + " found. Removing " + oldInfo - .getSessionId() + " & keeping " + mySessions.get(i).getSessionId()); - } - } - mOpenSessionMap = new HashMap(); - } - - /** - * This callback will be made after an installation attempt succeeds or fails. - */ - public interface InstallListener { - /** - * This callback signals that preflight checks have succeeded and installation - * is beginning. - */ - void installBeginning(); - - /** - * This callback signals that installation has completed. - */ - void installSucceeded(); - - /** - * This callback signals that installation has failed. - */ - void installFailed(int errorCode, String errorDesc); - } - - /** - * This is a placeholder implementation that bundles an entire "session" into a single - * call. This will be replaced by more granular versions that allow longer session lifetimes, - * download progress tracking, etc. - * - * This must not be called on main thread. - */ - public void install(final String packageName, ParcelFileDescriptor parcelFileDescriptor, - final InstallListener callback) { - // 0. Generic try/catch block because I am not really sure what exceptions (other than - // IOException) might be thrown by PackageInstaller and I want to handle them - // at least slightly gracefully. - try { - // 1. Create or recover a session, and open it - // Try recovery first - PackageInstaller.Session session = null; - PackageInstaller.SessionInfo sessionInfo = mSessionInfoMap.get(packageName); - if (sessionInfo != null) { - // See if it's openable, or already held open - session = getSession(packageName); - } - // If open failed, or there was no session, create a new one and open it. - // If we cannot create or open here, the failure is terminal. - if (session == null) { - try { - innerCreateSession(packageName); - } catch (IOException ioe) { - Log.e(TAG, "Can't create session for " + packageName + ": " + ioe.getMessage()); - callback.installFailed(InstallerConstants.ERROR_INSTALL_CREATE_SESSION, - "Could not create session"); - mSessionInfoMap.remove(packageName); - return; - } - sessionInfo = mSessionInfoMap.get(packageName); - try { - session = mPackageInstaller.openSession(sessionInfo.getSessionId()); - mOpenSessionMap.put(packageName, session); - } catch (SecurityException se) { - Log.e(TAG, "Can't open session for " + packageName + ": " + se.getMessage()); - callback.installFailed(InstallerConstants.ERROR_INSTALL_OPEN_SESSION, - "Can't open session"); - mSessionInfoMap.remove(packageName); - return; - } - } - - // 2. Launch task to handle file operations. - InstallTask task = new InstallTask( mContext, packageName, parcelFileDescriptor, - callback, session, - getCommitCallback(packageName, sessionInfo.getSessionId(), callback)); - task.execute(); - if (task.isError()) { - cancelSession(sessionInfo.getSessionId(), packageName); - } - } catch (Exception e) { - Log.e(TAG, "Unexpected exception while installing: " + packageName + ": " - + e.getMessage()); - callback.installFailed(InstallerConstants.ERROR_INSTALL_SESSION_EXCEPTION, - "Unexpected exception while installing " + packageName); - } - } - - /** - * Retrieve an existing session. Will open if needed, but does not attempt to create. - */ - private PackageInstaller.Session getSession(String packageName) { - // Check for already-open session - PackageInstaller.Session session = mOpenSessionMap.get(packageName); - if (session != null) { - try { - // Probe the session to ensure that it's still open. This may or may not - // throw (if non-open), but it may serve as a canary for stale sessions. - session.getNames(); - return session; - } catch (IOException ioe) { - Log.e(TAG, "Stale open session for " + packageName + ": " + ioe.getMessage()); - mOpenSessionMap.remove(packageName); - } catch (SecurityException se) { - Log.e(TAG, "Stale open session for " + packageName + ": " + se.getMessage()); - mOpenSessionMap.remove(packageName); - } - } - // Check to see if this is a known session - PackageInstaller.SessionInfo sessionInfo = mSessionInfoMap.get(packageName); - if (sessionInfo == null) { - return null; - } - // Try to open it. If we fail here, assume that the SessionInfo was stale. - try { - session = mPackageInstaller.openSession(sessionInfo.getSessionId()); - } catch (SecurityException se) { - Log.w(TAG, "SessionInfo was stale for " + packageName + " - deleting info"); - mSessionInfoMap.remove(packageName); - return null; - } catch (IOException ioe) { - Log.w(TAG, "IOException opening old session for " + ioe.getMessage() - + " - deleting info"); - mSessionInfoMap.remove(packageName); - return null; - } - mOpenSessionMap.put(packageName, session); - return session; - } - - /** This version throws an IOException when the session cannot be created */ - private void innerCreateSession(String packageName) throws IOException { - if (mSessionInfoMap.containsKey(packageName)) { - Log.w(TAG, "Creating session for " + packageName + " when one already exists"); - return; - } - PackageInstaller.SessionParams params = new PackageInstaller.SessionParams( - PackageInstaller.SessionParams.MODE_FULL_INSTALL); - params.setAppPackageName(packageName); - - // IOException may be thrown at this point - int sessionId = mPackageInstaller.createSession(params); - PackageInstaller.SessionInfo sessionInfo = mPackageInstaller.getSessionInfo(sessionId); - mSessionInfoMap.put(packageName, sessionInfo); - } - - /** - * Cancel a session based on its sessionId. Package name is for logging only. - */ - private void cancelSession(int sessionId, String packageName) { - // Close if currently held open - closeSession(packageName); - // Remove local record - mSessionInfoMap.remove(packageName); - try { - mPackageInstaller.abandonSession(sessionId); - } catch (SecurityException se) { - // The session no longer exists, so we can exit quietly. - return; - } - } - - /** - * Close a session if it happens to be held open. - */ - private void closeSession(String packageName) { - PackageInstaller.Session session = mOpenSessionMap.remove(packageName); - if (session != null) { - // Unfortunately close() is not idempotent. Try our best to make this safe. - try { - session.close(); - } catch (Exception e) { - Log.w(TAG, "Unexpected error closing session for " + packageName + ": " - + e.getMessage()); - } - } - } - - /** - * Creates a commit callback for the package install that's underway. This will be called - * some time after calling session.commit() (above). - */ - private IntentSender getCommitCallback(final String packageName, final int sessionId, - final InstallListener callback) { - // Create a single-use broadcast receiver - BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - mContext.unregisterReceiver(this); - handleCommitCallback(intent, packageName, sessionId, callback); - } - }; - // Create a matching intent-filter and register the receiver - String action = ACTION_INSTALL_COMMIT + "." + packageName; - IntentFilter intentFilter = new IntentFilter(); - intentFilter.addAction(action); - mContext.registerReceiver(broadcastReceiver, intentFilter); - - // Create a matching PendingIntent and use it to generate the IntentSender - Intent broadcastIntent = new Intent(action); - PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, packageName.hashCode(), - broadcastIntent, PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_UPDATE_CURRENT); - return pendingIntent.getIntentSender(); - } - - /** - * Examine the extras to determine information about the package update/install, decode - * the result, and call the appropriate callback. - * - * @param intent The intent, which the PackageInstaller will have added Extras to - * @param packageName The package name we created the receiver for - * @param sessionId The session Id we created the receiver for - * @param callback The callback to report success/failure to - */ - private void handleCommitCallback(Intent intent, String packageName, int sessionId, - InstallListener callback) { - if (Log.isLoggable(TAG, Log.DEBUG)) { - Log.d(TAG, "Installation of " + packageName + " finished with extras " - + intent.getExtras()); - } - String statusMessage = intent.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE); - int status = intent.getIntExtra(PackageInstaller.EXTRA_STATUS, Integer.MIN_VALUE); - if (status == PackageInstaller.STATUS_SUCCESS) { - cancelSession(sessionId, packageName); - callback.installSucceeded(); - } else if (status == -1 /*PackageInstaller.STATUS_USER_ACTION_REQUIRED*/) { - // TODO - use the constant when the correct/final name is in the SDK - // TODO This is unexpected, so we are treating as failure for now - cancelSession(sessionId, packageName); - callback.installFailed(InstallerConstants.ERROR_INSTALL_USER_ACTION_REQUIRED, - "Unexpected: user action required"); - } else { - cancelSession(sessionId, packageName); - int errorCode = getPackageManagerErrorCode(status); - Log.e(TAG, "Error " + errorCode + " while installing " + packageName + ": " - + statusMessage); - callback.installFailed(errorCode, null); - } - } - - private int getPackageManagerErrorCode(int status) { - // This is a hack: because PackageInstaller now reports error codes - // with small positive values, we need to remap them into a space - // that is more compatible with the existing package manager error codes. - // See https://sites.google.com/a/google.com/universal-store/documentation - // /android-client/download-error-codes - int errorCode; - if (status == Integer.MIN_VALUE) { - errorCode = InstallerConstants.ERROR_INSTALL_MALFORMED_BROADCAST; - } else { - errorCode = InstallerConstants.ERROR_PACKAGEINSTALLER_BASE - status; - } - return errorCode; - } -} diff --git a/src/com/android/packageinstaller/wear/WearPackageArgs.java b/src/com/android/packageinstaller/wear/WearPackageArgs.java deleted file mode 100644 index 2c289b2a6..000000000 --- a/src/com/android/packageinstaller/wear/WearPackageArgs.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2015 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.packageinstaller.wear; - -import android.content.Intent; -import android.net.Uri; -import android.os.Bundle; - -/** - * Installation Util that contains a list of parameters that are needed for - * installing/uninstalling. - */ -public class WearPackageArgs { - private static final String KEY_PACKAGE_NAME = - "com.google.android.clockwork.EXTRA_PACKAGE_NAME"; - private static final String KEY_ASSET_URI = - "com.google.android.clockwork.EXTRA_ASSET_URI"; - private static final String KEY_START_ID = - "com.google.android.clockwork.EXTRA_START_ID"; - private static final String KEY_PERM_URI = - "com.google.android.clockwork.EXTRA_PERM_URI"; - private static final String KEY_CHECK_PERMS = - "com.google.android.clockwork.EXTRA_CHECK_PERMS"; - private static final String KEY_SKIP_IF_SAME_VERSION = - "com.google.android.clockwork.EXTRA_SKIP_IF_SAME_VERSION"; - private static final String KEY_COMPRESSION_ALG = - "com.google.android.clockwork.EXTRA_KEY_COMPRESSION_ALG"; - private static final String KEY_COMPANION_SDK_VERSION = - "com.google.android.clockwork.EXTRA_KEY_COMPANION_SDK_VERSION"; - private static final String KEY_COMPANION_DEVICE_VERSION = - "com.google.android.clockwork.EXTRA_KEY_COMPANION_DEVICE_VERSION"; - private static final String KEY_SHOULD_CHECK_GMS_DEPENDENCY = - "com.google.android.clockwork.EXTRA_KEY_SHOULD_CHECK_GMS_DEPENDENCY"; - private static final String KEY_SKIP_IF_LOWER_VERSION = - "com.google.android.clockwork.EXTRA_SKIP_IF_LOWER_VERSION"; - - public static String getPackageName(Bundle b) { - return b.getString(KEY_PACKAGE_NAME); - } - - public static Bundle setPackageName(Bundle b, String packageName) { - b.putString(KEY_PACKAGE_NAME, packageName); - return b; - } - - public static Uri getAssetUri(Bundle b) { - return b.getParcelable(KEY_ASSET_URI); - } - - public static Uri getPermUri(Bundle b) { - return b.getParcelable(KEY_PERM_URI); - } - - public static boolean checkPerms(Bundle b) { - return b.getBoolean(KEY_CHECK_PERMS); - } - - public static boolean skipIfSameVersion(Bundle b) { - return b.getBoolean(KEY_SKIP_IF_SAME_VERSION); - } - - public static int getCompanionSdkVersion(Bundle b) { - return b.getInt(KEY_COMPANION_SDK_VERSION); - } - - public static int getCompanionDeviceVersion(Bundle b) { - return b.getInt(KEY_COMPANION_DEVICE_VERSION); - } - - public static String getCompressionAlg(Bundle b) { - return b.getString(KEY_COMPRESSION_ALG); - } - - public static int getStartId(Bundle b) { - return b.getInt(KEY_START_ID); - } - - public static boolean skipIfLowerVersion(Bundle b) { - return b.getBoolean(KEY_SKIP_IF_LOWER_VERSION, false); - } - - public static Bundle setStartId(Bundle b, int startId) { - b.putInt(KEY_START_ID, startId); - return b; - } -} diff --git a/src/com/android/packageinstaller/wear/WearPackageIconProvider.java b/src/com/android/packageinstaller/wear/WearPackageIconProvider.java deleted file mode 100644 index 02b9d298d..000000000 --- a/src/com/android/packageinstaller/wear/WearPackageIconProvider.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright (C) 2015 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.packageinstaller.wear; - -import android.annotation.TargetApi; -import android.app.ActivityManager; -import android.content.ContentProvider; -import android.content.ContentValues; -import android.content.Context; -import android.content.Intent; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.database.Cursor; -import android.net.Uri; -import android.os.Binder; -import android.os.Build; -import android.os.ParcelFileDescriptor; -import android.util.Log; - -import java.io.File; -import java.io.FileNotFoundException; -import java.util.List; - -import static android.content.pm.PackageManager.PERMISSION_GRANTED; - -public class WearPackageIconProvider extends ContentProvider { - private static final String TAG = "WearPackageIconProvider"; - public static final String AUTHORITY = "com.google.android.packageinstaller.wear.provider"; - - private static final String REQUIRED_PERMISSION = - "com.google.android.permission.INSTALL_WEARABLE_PACKAGES"; - - /** MIME types. */ - public static final String ICON_TYPE = "vnd.android.cursor.item/cw_package_icon"; - - @Override - public boolean onCreate() { - return true; - } - - @Override - public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, - String sortOrder) { - throw new UnsupportedOperationException("Query is not supported."); - } - - @Override - public String getType(Uri uri) { - if (uri == null) { - throw new IllegalArgumentException("URI passed in is null."); - } - - if (AUTHORITY.equals(uri.getEncodedAuthority())) { - return ICON_TYPE; - } - return null; - } - - @Override - public Uri insert(Uri uri, ContentValues values) { - throw new UnsupportedOperationException("Insert is not supported."); - } - - @Override - public int delete(Uri uri, String selection, String[] selectionArgs) { - if (uri == null) { - throw new IllegalArgumentException("URI passed in is null."); - } - - enforcePermissions(uri); - - if (ICON_TYPE.equals(getType(uri))) { - final File file = WearPackageUtil.getIconFile( - this.getContext().getApplicationContext(), getPackageNameFromUri(uri)); - if (file != null) { - file.delete(); - } - } - - return 0; - } - - @Override - public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { - throw new UnsupportedOperationException("Update is not supported."); - } - - @Override - public ParcelFileDescriptor openFile( - Uri uri, @SuppressWarnings("unused") String mode) throws FileNotFoundException { - if (uri == null) { - throw new IllegalArgumentException("URI passed in is null."); - } - - enforcePermissions(uri); - - if (ICON_TYPE.equals(getType(uri))) { - final File file = WearPackageUtil.getIconFile( - this.getContext().getApplicationContext(), getPackageNameFromUri(uri)); - if (file != null) { - return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY); - } - } - return null; - } - - public static Uri getUriForPackage(final String packageName) { - return Uri.parse("content://" + AUTHORITY + "/icons/" + packageName + ".icon"); - } - - private String getPackageNameFromUri(Uri uri) { - if (uri == null) { - return null; - } - List pathSegments = uri.getPathSegments(); - String packageName = pathSegments.get(pathSegments.size() - 1); - - if (packageName.endsWith(".icon")) { - packageName = packageName.substring(0, packageName.lastIndexOf(".")); - } - return packageName; - } - - /** - * Make sure the calling app is either a system app or the same app or has the right permission. - * @throws SecurityException if the caller has insufficient permissions. - */ - @TargetApi(Build.VERSION_CODES.BASE_1_1) - private void enforcePermissions(Uri uri) { - // Redo some of the permission check in {@link ContentProvider}. Just add an extra check to - // allow System process to access this provider. - Context context = getContext(); - final int pid = Binder.getCallingPid(); - final int uid = Binder.getCallingUid(); - final int myUid = android.os.Process.myUid(); - - if (uid == myUid || isSystemApp(context, pid)) { - return; - } - - if (context.checkPermission(REQUIRED_PERMISSION, pid, uid) == PERMISSION_GRANTED) { - return; - } - - // last chance, check against any uri grants - if (context.checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_READ_URI_PERMISSION) - == PERMISSION_GRANTED) { - return; - } - - throw new SecurityException("Permission Denial: reading " - + getClass().getName() + " uri " + uri + " from pid=" + pid - + ", uid=" + uid); - } - - /** - * From the pid of the calling process, figure out whether this is a system app or not. We do - * this by checking the application information corresponding to the pid and then checking if - * FLAG_SYSTEM is set. - */ - @TargetApi(Build.VERSION_CODES.CUPCAKE) - private boolean isSystemApp(Context context, int pid) { - // Get the Activity Manager Object - ActivityManager aManager = - (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); - // Get the list of running Applications - List rapInfoList = - aManager.getRunningAppProcesses(); - for (ActivityManager.RunningAppProcessInfo rapInfo : rapInfoList) { - if (rapInfo.pid == pid) { - try { - PackageInfo pkgInfo = context.getPackageManager().getPackageInfo( - rapInfo.pkgList[0], 0); - if (pkgInfo != null && pkgInfo.applicationInfo != null && - (pkgInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { - Log.d(TAG, pid + " is a system app."); - return true; - } - } catch (PackageManager.NameNotFoundException e) { - Log.e(TAG, "Could not find package information.", e); - return false; - } - } - } - return false; - } -} diff --git a/src/com/android/packageinstaller/wear/WearPackageInstallerService.java b/src/com/android/packageinstaller/wear/WearPackageInstallerService.java deleted file mode 100644 index e5f7613ab..000000000 --- a/src/com/android/packageinstaller/wear/WearPackageInstallerService.java +++ /dev/null @@ -1,589 +0,0 @@ -/* - * Copyright (C) 2015 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.packageinstaller.wear; - -import android.app.Notification; -import android.app.NotificationChannel; -import android.app.NotificationManager; -import android.app.Service; -import android.content.Context; -import android.content.Intent; -import android.content.pm.FeatureInfo; -import android.content.pm.IPackageDeleteObserver; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageParser; -import android.database.Cursor; -import android.net.Uri; -import android.os.Build; -import android.os.Bundle; -import android.os.Handler; -import android.os.HandlerThread; -import android.os.IBinder; -import android.os.Looper; -import android.os.Message; -import android.os.ParcelFileDescriptor; -import android.os.PowerManager; -import android.os.Process; -import android.util.ArrayMap; -import android.util.Log; -import android.util.Pair; - -import com.android.packageinstaller.DeviceUtils; -import com.android.packageinstaller.PackageUtil; -import com.android.packageinstaller.R; - -import java.io.File; -import java.io.FileNotFoundException; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * Service that will install/uninstall packages. It will check for permissions and features as well. - * - * ----------- - * - * Debugging information: - * - * Install Action example: - * adb shell am startservice -a com.android.packageinstaller.wear.INSTALL_PACKAGE \ - * -d package://com.google.android.gms \ - * --eu com.google.android.clockwork.EXTRA_ASSET_URI content://com.google.android.clockwork.home.provider/host/com.google.android.wearable.app/wearable/com.google.android.gms/apk \ - * --es android.intent.extra.INSTALLER_PACKAGE_NAME com.google.android.gms \ - * --ez com.google.android.clockwork.EXTRA_CHECK_PERMS false \ - * --eu com.google.android.clockwork.EXTRA_PERM_URI content://com.google.android.clockwork.home.provider/host/com.google.android.wearable.app/permissions \ - * com.android.packageinstaller/com.android.packageinstaller.wear.WearPackageInstallerService - * - * Uninstall Action example: - * adb shell am startservice -a com.android.packageinstaller.wear.UNINSTALL_PACKAGE \ - * -d package://com.google.android.gms \ - * com.android.packageinstaller/com.android.packageinstaller.wear.WearPackageInstallerService - * - * Retry GMS: - * adb shell am startservice -a com.android.packageinstaller.wear.RETRY_GMS \ - * com.android.packageinstaller/com.android.packageinstaller.wear.WearPackageInstallerService - */ -public class WearPackageInstallerService extends Service { - private static final String TAG = "WearPkgInstallerService"; - - private static final String WEAR_APPS_CHANNEL = "wear_app_install_uninstall"; - - private final int START_INSTALL = 1; - private final int START_UNINSTALL = 2; - - private int mInstallNotificationId = 1; - private final Map mNotifIdMap = new ArrayMap<>(); - - private final class ServiceHandler extends Handler { - public ServiceHandler(Looper looper) { - super(looper); - } - - public void handleMessage(Message msg) { - switch (msg.what) { - case START_INSTALL: - installPackage(msg.getData()); - break; - case START_UNINSTALL: - uninstallPackage(msg.getData()); - break; - } - } - } - private ServiceHandler mServiceHandler; - private NotificationChannel mNotificationChannel; - private static volatile PowerManager.WakeLock lockStatic = null; - - @Override - public IBinder onBind(Intent intent) { - return null; - } - - @Override - public void onCreate() { - super.onCreate(); - HandlerThread thread = new HandlerThread("PackageInstallerThread", - Process.THREAD_PRIORITY_BACKGROUND); - thread.start(); - - mServiceHandler = new ServiceHandler(thread.getLooper()); - } - - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - if (!DeviceUtils.isWear(this)) { - Log.w(TAG, "Not running on wearable."); - finishServiceEarly(startId); - return START_NOT_STICKY; - } - - if (intent == null) { - Log.w(TAG, "Got null intent."); - finishServiceEarly(startId); - return START_NOT_STICKY; - } - - if (Log.isLoggable(TAG, Log.DEBUG)) { - Log.d(TAG, "Got install/uninstall request " + intent); - } - - Uri packageUri = intent.getData(); - if (packageUri == null) { - Log.e(TAG, "No package URI in intent"); - finishServiceEarly(startId); - return START_NOT_STICKY; - } - - final String packageName = WearPackageUtil.getSanitizedPackageName(packageUri); - if (packageName == null) { - Log.e(TAG, "Invalid package name in URI (expected package:): " + packageUri); - finishServiceEarly(startId); - return START_NOT_STICKY; - } - - PowerManager.WakeLock lock = getLock(this.getApplicationContext()); - if (!lock.isHeld()) { - lock.acquire(); - } - - Bundle intentBundle = intent.getExtras(); - if (intentBundle == null) { - intentBundle = new Bundle(); - } - WearPackageArgs.setStartId(intentBundle, startId); - WearPackageArgs.setPackageName(intentBundle, packageName); - Message msg; - String notifTitle; - if (Intent.ACTION_INSTALL_PACKAGE.equals(intent.getAction())) { - msg = mServiceHandler.obtainMessage(START_INSTALL); - notifTitle = getString(R.string.installing); - } else if (Intent.ACTION_UNINSTALL_PACKAGE.equals(intent.getAction())) { - msg = mServiceHandler.obtainMessage(START_UNINSTALL); - notifTitle = getString(R.string.uninstalling); - } else { - Log.e(TAG, "Unknown action : " + intent.getAction()); - finishServiceEarly(startId); - return START_NOT_STICKY; - } - Pair notifPair = buildNotification(packageName, notifTitle); - startForeground(notifPair.first, notifPair.second); - msg.setData(intentBundle); - mServiceHandler.sendMessage(msg); - return START_NOT_STICKY; - } - - private void installPackage(Bundle argsBundle) { - int startId = WearPackageArgs.getStartId(argsBundle); - final String packageName = WearPackageArgs.getPackageName(argsBundle); - final Uri assetUri = WearPackageArgs.getAssetUri(argsBundle); - final Uri permUri = WearPackageArgs.getPermUri(argsBundle); - boolean checkPerms = WearPackageArgs.checkPerms(argsBundle); - boolean skipIfSameVersion = WearPackageArgs.skipIfSameVersion(argsBundle); - int companionSdkVersion = WearPackageArgs.getCompanionSdkVersion(argsBundle); - int companionDeviceVersion = WearPackageArgs.getCompanionDeviceVersion(argsBundle); - String compressionAlg = WearPackageArgs.getCompressionAlg(argsBundle); - boolean skipIfLowerVersion = WearPackageArgs.skipIfLowerVersion(argsBundle); - - if (Log.isLoggable(TAG, Log.DEBUG)) { - Log.d(TAG, "Installing package: " + packageName + ", assetUri: " + assetUri + - ",permUri: " + permUri + ", startId: " + startId + ", checkPerms: " + - checkPerms + ", skipIfSameVersion: " + skipIfSameVersion + - ", compressionAlg: " + compressionAlg + ", companionSdkVersion: " + - companionSdkVersion + ", companionDeviceVersion: " + companionDeviceVersion + - ", skipIfLowerVersion: " + skipIfLowerVersion); - } - final PackageManager pm = getPackageManager(); - File tempFile = null; - int installFlags = 0; - PowerManager.WakeLock lock = getLock(this.getApplicationContext()); - boolean messageSent = false; - try { - PackageInfo existingPkgInfo = null; - try { - existingPkgInfo = pm.getPackageInfo(packageName, - PackageManager.MATCH_ANY_USER | PackageManager.GET_PERMISSIONS); - if (existingPkgInfo != null) { - installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; - } - } catch (PackageManager.NameNotFoundException e) { - // Ignore this exception. We could not find the package, will treat as a new - // installation. - } - if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) { - if (Log.isLoggable(TAG, Log.DEBUG)) { - Log.d(TAG, "Replacing package:" + packageName); - } - } - // TODO(28021618): This was left as a temp file due to the fact that this code is being - // deprecated and that we need the bare minimum to continue working moving forward - // If this code is used as reference, this permission logic might want to be - // reworked to use a stream instead of a file so that we don't need to write a - // file at all. Note that there might be some trickiness with opening a stream - // for multiple users. - ParcelFileDescriptor parcelFd = getContentResolver() - .openFileDescriptor(assetUri, "r"); - tempFile = WearPackageUtil.getFileFromFd(WearPackageInstallerService.this, - parcelFd, packageName, compressionAlg); - if (tempFile == null) { - Log.e(TAG, "Could not create a temp file from FD for " + packageName); - return; - } - PackageParser.Package pkg = PackageUtil.getPackageInfo(this, tempFile); - if (pkg == null) { - Log.e(TAG, "Could not parse apk information for " + packageName); - return; - } - - if (!pkg.packageName.equals(packageName)) { - Log.e(TAG, "Wearable Package Name has to match what is provided for " + - packageName); - return; - } - - pkg.applicationInfo.sourceDir = tempFile.getPath(); - pkg.applicationInfo.publicSourceDir = tempFile.getPath(); - getLabelAndUpdateNotification(packageName, - getString(R.string.installing_app, pkg.applicationInfo.loadLabel(pm))); - - List wearablePerms = pkg.requestedPermissions; - - // Log if the installed pkg has a higher version number. - if (existingPkgInfo != null) { - if (existingPkgInfo.getLongVersionCode() == pkg.getLongVersionCode()) { - if (skipIfSameVersion) { - Log.w(TAG, "Version number (" + pkg.getLongVersionCode() + - ") of new app is equal to existing app for " + packageName + - "; not installing due to versionCheck"); - return; - } else { - Log.w(TAG, "Version number of new app (" + pkg.getLongVersionCode() + - ") is equal to existing app for " + packageName); - } - } else if (existingPkgInfo.getLongVersionCode() > pkg.getLongVersionCode()) { - if (skipIfLowerVersion) { - // Starting in Feldspar, we are not going to allow downgrades of any app. - Log.w(TAG, "Version number of new app (" + pkg.getLongVersionCode() + - ") is lower than existing app ( " - + existingPkgInfo.getLongVersionCode() + - ") for " + packageName + "; not installing due to versionCheck"); - return; - } else { - Log.w(TAG, "Version number of new app (" + pkg.getLongVersionCode() + - ") is lower than existing app ( " - + existingPkgInfo.getLongVersionCode() + ") for " + packageName); - } - } - - // Following the Android Phone model, we should only check for permissions for any - // newly defined perms. - if (existingPkgInfo.requestedPermissions != null) { - for (int i = 0; i < existingPkgInfo.requestedPermissions.length; ++i) { - // If the permission is granted, then we will not ask to request it again. - if ((existingPkgInfo.requestedPermissionsFlags[i] & - PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0) { - if (Log.isLoggable(TAG, Log.DEBUG)) { - Log.d(TAG, existingPkgInfo.requestedPermissions[i] + - " is already granted for " + packageName); - } - wearablePerms.remove(existingPkgInfo.requestedPermissions[i]); - } - } - } - } - - // Check that the wearable has all the features. - boolean hasAllFeatures = true; - if (pkg.reqFeatures != null) { - for (FeatureInfo feature : pkg.reqFeatures) { - if (feature.name != null && !pm.hasSystemFeature(feature.name) && - (feature.flags & FeatureInfo.FLAG_REQUIRED) != 0) { - Log.e(TAG, "Wearable does not have required feature: " + feature + - " for " + packageName); - hasAllFeatures = false; - } - } - } - - if (!hasAllFeatures) { - return; - } - - // Check permissions on both the new wearable package and also on the already installed - // wearable package. - // If the app is targeting API level 23, we will also start a service in ClockworkHome - // which will ultimately prompt the user to accept/reject permissions. - if (checkPerms && !checkPermissions(pkg, companionSdkVersion, companionDeviceVersion, - permUri, wearablePerms, tempFile)) { - Log.w(TAG, "Wearable does not have enough permissions."); - return; - } - - // Finally install the package. - ParcelFileDescriptor fd = getContentResolver().openFileDescriptor(assetUri, "r"); - PackageInstallerFactory.getPackageInstaller(this).install(packageName, fd, - new PackageInstallListener(this, lock, startId, packageName)); - - messageSent = true; - Log.i(TAG, "Sent installation request for " + packageName); - } catch (FileNotFoundException e) { - Log.e(TAG, "Could not find the file with URI " + assetUri, e); - } finally { - if (!messageSent) { - // Some error happened. If the message has been sent, we can wait for the observer - // which will finish the service. - if (tempFile != null) { - tempFile.delete(); - } - finishService(lock, startId); - } - } - } - - // TODO: This was left using the old PackageManager API due to the fact that this code is being - // deprecated and that we need the bare minimum to continue working moving forward - // If this code is used as reference, this logic should be reworked to use the new - // PackageInstaller APIs similar to how installPackage was reworked - private void uninstallPackage(Bundle argsBundle) { - int startId = WearPackageArgs.getStartId(argsBundle); - final String packageName = WearPackageArgs.getPackageName(argsBundle); - - PowerManager.WakeLock lock = getLock(this.getApplicationContext()); - final PackageManager pm = getPackageManager(); - try { - PackageInfo pkgInfo = pm.getPackageInfo(packageName, 0); - getLabelAndUpdateNotification(packageName, - getString(R.string.uninstalling_app, pkgInfo.applicationInfo.loadLabel(pm))); - - // Found package, send uninstall request. - pm.deletePackage(packageName, new PackageDeleteObserver(lock, startId), - PackageManager.DELETE_ALL_USERS); - - Log.i(TAG, "Sent delete request for " + packageName); - } catch (IllegalArgumentException | PackageManager.NameNotFoundException e) { - // Couldn't find the package, no need to call uninstall. - Log.w(TAG, "Could not find package, not deleting " + packageName, e); - finishService(lock, startId); - } - } - - private boolean checkPermissions(PackageParser.Package pkg, int companionSdkVersion, - int companionDeviceVersion, Uri permUri, List wearablePermissions, - File apkFile) { - // Assumption: We are running on Android O. - // If the Phone App is targeting M, all permissions may not have been granted to the phone - // app. If the Wear App is then not targeting M, there may be permissions that are not - // granted on the Phone app (by the user) right now and we cannot just grant it for the Wear - // app. - if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) { - // Install the app if Wear App is ready for the new perms model. - return true; - } - - if (!doesWearHaveUngrantedPerms(pkg.packageName, permUri, wearablePermissions)) { - // All permissions requested by the watch are already granted on the phone, no need - // to do anything. - return true; - } - - // Log an error if Wear is targeting < 23 and phone is targeting >= 23. - if (companionSdkVersion == 0 || companionSdkVersion >= Build.VERSION_CODES.M) { - Log.e(TAG, "MNC: Wear app's targetSdkVersion should be at least 23, if " - + "phone app is targeting at least 23, will continue."); - } - - return false; - } - - /** - * Given a {@string packageName} corresponding to a phone app, query the provider for all the - * perms that are granted. - * - * @return true if the Wear App has any perms that have not been granted yet on the phone side. - * @return true if there is any error cases. - */ - private boolean doesWearHaveUngrantedPerms(String packageName, Uri permUri, - List wearablePermissions) { - if (permUri == null) { - Log.e(TAG, "Permission URI is null"); - // Pretend there is an ungranted permission to avoid installing for error cases. - return true; - } - Cursor permCursor = getContentResolver().query(permUri, null, null, null, null); - if (permCursor == null) { - Log.e(TAG, "Could not get the cursor for the permissions"); - // Pretend there is an ungranted permission to avoid installing for error cases. - return true; - } - - Set grantedPerms = new HashSet<>(); - Set ungrantedPerms = new HashSet<>(); - while(permCursor.moveToNext()) { - // Make sure that the MatrixCursor returned by the ContentProvider has 2 columns and - // verify their types. - if (permCursor.getColumnCount() == 2 - && Cursor.FIELD_TYPE_STRING == permCursor.getType(0) - && Cursor.FIELD_TYPE_INTEGER == permCursor.getType(1)) { - String perm = permCursor.getString(0); - Integer granted = permCursor.getInt(1); - if (granted == 1) { - grantedPerms.add(perm); - } else { - ungrantedPerms.add(perm); - } - } - } - permCursor.close(); - - boolean hasUngrantedPerm = false; - for (String wearablePerm : wearablePermissions) { - if (!grantedPerms.contains(wearablePerm)) { - hasUngrantedPerm = true; - if (!ungrantedPerms.contains(wearablePerm)) { - // This is an error condition. This means that the wearable has permissions that - // are not even declared in its host app. This is a developer error. - Log.e(TAG, "Wearable " + packageName + " has a permission \"" + wearablePerm - + "\" that is not defined in the host application's manifest."); - } else { - Log.w(TAG, "Wearable " + packageName + " has a permission \"" + wearablePerm + - "\" that is not granted in the host application."); - } - } - } - return hasUngrantedPerm; - } - - /** Finishes the service after fulfilling obligation to call startForeground. */ - private void finishServiceEarly(int startId) { - Pair notifPair = buildNotification( - getApplicationContext().getPackageName(), ""); - startForeground(notifPair.first, notifPair.second); - finishService(null, startId); - } - - private void finishService(PowerManager.WakeLock lock, int startId) { - if (lock != null && lock.isHeld()) { - lock.release(); - } - stopSelf(startId); - } - - private synchronized PowerManager.WakeLock getLock(Context context) { - if (lockStatic == null) { - PowerManager mgr = - (PowerManager) context.getSystemService(Context.POWER_SERVICE); - lockStatic = mgr.newWakeLock( - PowerManager.PARTIAL_WAKE_LOCK, context.getClass().getSimpleName()); - lockStatic.setReferenceCounted(true); - } - return lockStatic; - } - - private class PackageInstallListener implements PackageInstallerImpl.InstallListener { - private Context mContext; - private PowerManager.WakeLock mWakeLock; - private int mStartId; - private String mApplicationPackageName; - private PackageInstallListener(Context context, PowerManager.WakeLock wakeLock, - int startId, String applicationPackageName) { - mContext = context; - mWakeLock = wakeLock; - mStartId = startId; - mApplicationPackageName = applicationPackageName; - } - - @Override - public void installBeginning() { - Log.i(TAG, "Package " + mApplicationPackageName + " is being installed."); - } - - @Override - public void installSucceeded() { - try { - Log.i(TAG, "Package " + mApplicationPackageName + " was installed."); - - // Delete tempFile from the file system. - File tempFile = WearPackageUtil.getTemporaryFile(mContext, mApplicationPackageName); - if (tempFile != null) { - tempFile.delete(); - } - } finally { - finishService(mWakeLock, mStartId); - } - } - - @Override - public void installFailed(int errorCode, String errorDesc) { - Log.e(TAG, "Package install failed " + mApplicationPackageName - + ", errorCode " + errorCode); - finishService(mWakeLock, mStartId); - } - } - - private class PackageDeleteObserver extends IPackageDeleteObserver.Stub { - private PowerManager.WakeLock mWakeLock; - private int mStartId; - - private PackageDeleteObserver(PowerManager.WakeLock wakeLock, int startId) { - mWakeLock = wakeLock; - mStartId = startId; - } - - public void packageDeleted(String packageName, int returnCode) { - try { - if (returnCode >= 0) { - Log.i(TAG, "Package " + packageName + " was uninstalled."); - } else { - Log.e(TAG, "Package uninstall failed " + packageName + ", returnCode " + - returnCode); - } - } finally { - finishService(mWakeLock, mStartId); - } - } - } - - private synchronized Pair buildNotification(final String packageName, - final String title) { - int notifId; - if (mNotifIdMap.containsKey(packageName)) { - notifId = mNotifIdMap.get(packageName); - } else { - notifId = mInstallNotificationId++; - mNotifIdMap.put(packageName, notifId); - } - - if (mNotificationChannel == null) { - mNotificationChannel = new NotificationChannel(WEAR_APPS_CHANNEL, - getString(R.string.wear_app_channel), NotificationManager.IMPORTANCE_MIN); - NotificationManager notificationManager = getSystemService(NotificationManager.class); - notificationManager.createNotificationChannel(mNotificationChannel); - } - return new Pair<>(notifId, new Notification.Builder(this, WEAR_APPS_CHANNEL) - .setSmallIcon(R.drawable.ic_file_download) - .setContentTitle(title) - .build()); - } - - private void getLabelAndUpdateNotification(String packageName, String title) { - // Update notification since we have a label now. - NotificationManager notificationManager = getSystemService(NotificationManager.class); - Pair notifPair = buildNotification(packageName, title); - notificationManager.notify(notifPair.first, notifPair.second); - } -} diff --git a/src/com/android/packageinstaller/wear/WearPackageUtil.java b/src/com/android/packageinstaller/wear/WearPackageUtil.java deleted file mode 100644 index bc740ab15..000000000 --- a/src/com/android/packageinstaller/wear/WearPackageUtil.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (C) 2015 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.packageinstaller.wear; - -import android.content.Context; -import android.net.Uri; -import android.os.ParcelFileDescriptor; -import android.system.ErrnoException; -import android.system.Os; -import android.text.TextUtils; -import android.util.Log; - -import org.tukaani.xz.LZMAInputStream; -import org.tukaani.xz.XZInputStream; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; - -public class WearPackageUtil { - private static final String TAG = "WearablePkgInstaller"; - - private static final String COMPRESSION_LZMA = "lzma"; - private static final String COMPRESSION_XZ = "xz"; - - public static File getTemporaryFile(Context context, String packageName) { - try { - File newFileDir = new File(context.getFilesDir(), "tmp"); - newFileDir.mkdirs(); - Os.chmod(newFileDir.getAbsolutePath(), 0771); - File newFile = new File(newFileDir, packageName + ".apk"); - return newFile; - } catch (ErrnoException e) { - Log.e(TAG, "Failed to open.", e); - return null; - } - } - - public static File getIconFile(final Context context, final String packageName) { - try { - File newFileDir = new File(context.getFilesDir(), "images/icons"); - newFileDir.mkdirs(); - Os.chmod(newFileDir.getAbsolutePath(), 0771); - return new File(newFileDir, packageName + ".icon"); - } catch (ErrnoException e) { - Log.e(TAG, "Failed to open.", e); - return null; - } - } - - /** - * In order to make sure that the Wearable Asset Manager has a reasonable apk that can be used - * by the PackageManager, we will parse it before sending it to the PackageManager. - * Unfortunately, PackageParser needs a file to parse. So, we have to temporarily convert the fd - * to a File. - * - * @param context - * @param fd FileDescriptor to convert to File - * @param packageName Name of package, will define the name of the file - * @param compressionAlg Can be null. For ALT mode the APK will be compressed. We will - * decompress it here - */ - public static File getFileFromFd(Context context, ParcelFileDescriptor fd, - String packageName, String compressionAlg) { - File newFile = getTemporaryFile(context, packageName); - if (fd == null || fd.getFileDescriptor() == null) { - return null; - } - InputStream fr = new ParcelFileDescriptor.AutoCloseInputStream(fd); - try { - if (TextUtils.equals(compressionAlg, COMPRESSION_XZ)) { - fr = new XZInputStream(fr); - } else if (TextUtils.equals(compressionAlg, COMPRESSION_LZMA)) { - fr = new LZMAInputStream(fr); - } - } catch (IOException e) { - Log.e(TAG, "Compression was set to " + compressionAlg + ", but could not decode ", e); - return null; - } - - int nRead; - byte[] data = new byte[1024]; - try { - final FileOutputStream fo = new FileOutputStream(newFile); - while ((nRead = fr.read(data, 0, data.length)) != -1) { - fo.write(data, 0, nRead); - } - fo.flush(); - fo.close(); - Os.chmod(newFile.getAbsolutePath(), 0644); - return newFile; - } catch (IOException e) { - Log.e(TAG, "Reading from Asset FD or writing to temp file failed ", e); - return null; - } catch (ErrnoException e) { - Log.e(TAG, "Could not set permissions on file ", e); - return null; - } finally { - try { - fr.close(); - } catch (IOException e) { - Log.e(TAG, "Failed to close the file from FD ", e); - } - } - } - - /** - * @return com.google.com from expected formats like - * Uri: package:com.google.com, package:/com.google.com, package://com.google.com - */ - public static String getSanitizedPackageName(Uri packageUri) { - String packageName = packageUri.getEncodedSchemeSpecificPart(); - if (packageName != null) { - return packageName.replaceAll("^/+", ""); - } - return packageName; - } -} -- GitLab From 450de4e9d91fbba88ba109fde0c3aae0efd661e6 Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Mon, 30 Jul 2018 13:11:08 -0700 Subject: [PATCH 058/701] Allow dark theme in permission grant dialog Test: Looked at permission grant dialog in dark mode and light mode Change-Id: I5c31666ee8e6da285267c8986f80a096366a53f1 --- res/layout/grant_permissions.xml | 2 +- res/layout/grant_permissions_content.xml | 2 +- res/values/themes.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/res/layout/grant_permissions.xml b/res/layout/grant_permissions.xml index f2a041fd0..697403738 100644 --- a/res/layout/grant_permissions.xml +++ b/res/layout/grant_permissions.xml @@ -44,7 +44,7 @@ + android:theme="@*android:style/Theme.DeviceDefault.PermissionGrant"> - - - + + diff --git a/src/com/android/packageinstaller/permission/model/AppPermissions.java b/src/com/android/packageinstaller/permission/model/AppPermissions.java index c5feec93f..125074f48 100644 --- a/src/com/android/packageinstaller/permission/model/AppPermissions.java +++ b/src/com/android/packageinstaller/permission/model/AppPermissions.java @@ -16,15 +16,13 @@ package com.android.packageinstaller.permission.model; -import static com.android.packageinstaller.permission.utils.Utils.DEFAULT_MAX_LABEL_SIZE_PX; - import android.content.Context; import android.content.pm.PackageInfo; -import android.content.pm.PackageItemInfo; import android.content.pm.PackageManager; -import android.text.BidiFormatter; import android.util.ArrayMap; +import com.android.packageinstaller.permission.utils.Utils; + import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -69,12 +67,7 @@ public final class AppPermissions { boolean delayChanges, Runnable onErrorCallback) { mContext = context; mPackageInfo = packageInfo; - mAppLabel = BidiFormatter.getInstance().unicodeWrap( - packageInfo.applicationInfo.loadSafeLabel(context.getPackageManager(), - DEFAULT_MAX_LABEL_SIZE_PX, - PackageItemInfo.SAFE_LABEL_FLAG_TRIM - | PackageItemInfo.SAFE_LABEL_FLAG_FIRST_LINE) - .toString()); + mAppLabel = Utils.getAppLabel(packageInfo.applicationInfo, context); mSortGroups = sortGroups; mDelayChanges = delayChanges; mOnErrorCallback = onErrorCallback; diff --git a/src/com/android/packageinstaller/permission/utils/Utils.java b/src/com/android/packageinstaller/permission/utils/Utils.java index d5376f196..78a97784b 100644 --- a/src/com/android/packageinstaller/permission/utils/Utils.java +++ b/src/com/android/packageinstaller/permission/utils/Utils.java @@ -26,12 +26,14 @@ import android.content.res.Resources; import android.content.res.Resources.Theme; import android.graphics.drawable.Drawable; import android.text.Html; +import android.text.TextUtils; import android.util.ArraySet; import android.util.Log; import android.util.TypedValue; import androidx.annotation.NonNull; import androidx.annotation.StringRes; +import androidx.core.text.BidiFormatter; import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.model.AppPermissions; @@ -71,6 +73,23 @@ public final class Utils { /* do nothing - hide constructor */ } + /** + * Get the label for an application. + * + * @param applicationInfo the {@link ApplicationInfo} of the application + * @param context the {@code Context} to retrieve {@code PackageManager} + * + * @return the label for the application + */ + @NonNull + public static String getAppLabel(@NonNull ApplicationInfo applicationInfo, + @NonNull Context context) { + return BidiFormatter.getInstance().unicodeWrap(applicationInfo.loadSafeLabel( + context.getPackageManager(), DEFAULT_MAX_LABEL_SIZE_PX, + TextUtils.SAFE_STRING_FLAG_TRIM | TextUtils.SAFE_STRING_FLAG_FIRST_LINE) + .toString()); + } + public static Drawable loadDrawable(PackageManager pm, String pkg, int resId) { try { return pm.getResourcesForApplication(pkg).getDrawable(resId, null); diff --git a/src/com/android/packageinstaller/role/model/Permissions.java b/src/com/android/packageinstaller/role/model/Permissions.java index 8766ac0a2..a5906fa3b 100644 --- a/src/com/android/packageinstaller/role/model/Permissions.java +++ b/src/com/android/packageinstaller/role/model/Permissions.java @@ -35,7 +35,7 @@ import androidx.annotation.Nullable; import com.android.packageinstaller.permission.utils.ArrayUtils; import com.android.packageinstaller.permission.utils.CollectionUtils; -import com.android.packageinstaller.role.utils.Utils; +import com.android.packageinstaller.role.utils.PackageUtils; import java.util.ArrayList; import java.util.List; @@ -483,7 +483,7 @@ public class Permissions { @Nullable private static PackageInfo getPackageInfo(@NonNull String packageName, int extraFlags, @NonNull Context context) { - return Utils.getPackageInfo(packageName, extraFlags + return PackageUtils.getPackageInfo(packageName, extraFlags // TODO: Why MATCH_UNINSTALLED_PACKAGES? | PackageManager.MATCH_UNINSTALLED_PACKAGES | PackageManager.GET_PERMISSIONS, context); @@ -496,7 +496,7 @@ public class Permissions { static boolean isRuntimePermissionsSupported(@NonNull String packageName, @NonNull Context context) { - ApplicationInfo applicationInfo = Utils.getApplicationInfo(packageName, context); + ApplicationInfo applicationInfo = PackageUtils.getApplicationInfo(packageName, context); if (applicationInfo == null) { return false; } @@ -685,7 +685,7 @@ public class Permissions { @Nullable private static Integer getAppOpMode(@NonNull String packageName, @NonNull String appOp, @NonNull Context context) { - ApplicationInfo applicationInfo = Utils.getApplicationInfo(packageName, context); + ApplicationInfo applicationInfo = PackageUtils.getApplicationInfo(packageName, context); if (applicationInfo == null) { return null; } @@ -703,7 +703,7 @@ public class Permissions { if (currentMode != null && currentMode == mode) { return false; } - ApplicationInfo applicationInfo = Utils.getApplicationInfo(packageName, context); + ApplicationInfo applicationInfo = PackageUtils.getApplicationInfo(packageName, context); if (applicationInfo == null) { Log.e(LOG_TAG, "Cannot get ApplicationInfo for package to set app op mode: " + packageName); diff --git a/src/com/android/packageinstaller/role/model/Role.java b/src/com/android/packageinstaller/role/model/Role.java index 48829ad98..adbe49a5e 100644 --- a/src/com/android/packageinstaller/role/model/Role.java +++ b/src/com/android/packageinstaller/role/model/Role.java @@ -25,7 +25,7 @@ import android.util.Log; import androidx.annotation.NonNull; -import com.android.packageinstaller.role.utils.Utils; +import com.android.packageinstaller.role.utils.PackageUtils; import java.util.ArrayList; import java.util.List; @@ -260,7 +260,7 @@ public class Role { } private void killApp(@NonNull String packageName, @NonNull Context context) { - ApplicationInfo applicationInfo = Utils.getApplicationInfo(packageName, context); + ApplicationInfo applicationInfo = PackageUtils.getApplicationInfo(packageName, context); if (applicationInfo == null) { Log.w(LOG_TAG, "Cannot get ApplicationInfo for package: " + packageName); return; diff --git a/src/com/android/packageinstaller/role/service/RoleControllerServiceImpl.java b/src/com/android/packageinstaller/role/service/RoleControllerServiceImpl.java index 4c14d59f9..0226676f0 100644 --- a/src/com/android/packageinstaller/role/service/RoleControllerServiceImpl.java +++ b/src/com/android/packageinstaller/role/service/RoleControllerServiceImpl.java @@ -30,7 +30,7 @@ import androidx.annotation.WorkerThread; import com.android.packageinstaller.role.model.Role; import com.android.packageinstaller.role.model.Roles; -import com.android.packageinstaller.role.utils.Utils; +import com.android.packageinstaller.role.utils.PackageUtils; import java.util.List; @@ -129,7 +129,7 @@ public class RoleControllerServiceImpl extends RoleControllerService { return; } - ApplicationInfo applicationInfo = Utils.getApplicationInfo(packageName, this); + ApplicationInfo applicationInfo = PackageUtils.getApplicationInfo(packageName, this); if (applicationInfo == null) { Log.e(LOG_TAG, "Cannot get ApplicationInfo for package: " + packageName); callback.onFailure(); @@ -150,13 +150,13 @@ public class RoleControllerServiceImpl extends RoleControllerService { } if (role.isExclusive()) { - List previousPackageNames = mRoleManager.getRoleHolders(roleName); - int previousPackageNamesSize = previousPackageNames.size(); - for (int i = 0; i < previousPackageNamesSize; i++) { - String previousPackageName = previousPackageNames.get(i); - boolean removed = removeRoleHolderInternal(role, previousPackageName); + List currentPackageNames = mRoleManager.getRoleHolders(roleName); + int currentPackageNamesSize = currentPackageNames.size(); + for (int i = 0; i < currentPackageNamesSize; i++) { + String currentPackageName = currentPackageNames.get(i); + boolean removed = removeRoleHolderInternal(role, currentPackageName); if (!removed) { - Log.e(LOG_TAG, "Failed to remove previous holder from role holders in" + Log.e(LOG_TAG, "Failed to remove current holder from role holders in" + " RoleManager, package: " + packageName + ", role: " + roleName); // TODO: Clean up? callback.onFailure(); @@ -227,7 +227,7 @@ public class RoleControllerServiceImpl extends RoleControllerService { @WorkerThread private boolean removeRoleHolderInternal(@NonNull Role role, @NonNull String packageName) { - ApplicationInfo applicationInfo = Utils.getApplicationInfo(packageName, this); + ApplicationInfo applicationInfo = PackageUtils.getApplicationInfo(packageName, this); if (applicationInfo == null) { Log.w(LOG_TAG, "Cannot get ApplicationInfo for package: " + packageName); } diff --git a/src/com/android/packageinstaller/role/ui/RequestRoleActivity.java b/src/com/android/packageinstaller/role/ui/RequestRoleActivity.java new file mode 100644 index 000000000..405f3cda4 --- /dev/null +++ b/src/com/android/packageinstaller/role/ui/RequestRoleActivity.java @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.packageinstaller.role.ui; + +import android.app.role.RoleManager; +import android.os.Bundle; +import android.text.TextUtils; +import android.util.Log; +import android.view.WindowManager; + +import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentActivity; + +import com.android.packageinstaller.role.model.Role; +import com.android.packageinstaller.role.model.Roles; +import com.android.packageinstaller.role.utils.PackageUtils; + +import java.util.List; + +/** + * {@code Activity} for a role request. + */ +public class RequestRoleActivity extends FragmentActivity { + + private static final String LOG_TAG = RequestRoleActivity.class.getSimpleName(); + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + getWindow().addSystemFlags( + WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS); + + String roleName = getIntent().getStringExtra(RoleManager.EXTRA_REQUEST_ROLE_NAME); + if (TextUtils.isEmpty(roleName)) { + Log.w(LOG_TAG, "Role name cannot be null or empty: " + roleName); + finish(); + return; + } + + // TODO: Allow proxy package? + String packageName = getCallingPackage(); + if (TextUtils.isEmpty(packageName)) { + Log.w(LOG_TAG, "Package name cannot be null or empty: " + packageName); + finish(); + return; + } + + // Perform checks here so that we have a chance to finish without being visible to user. + Role role = Roles.getRoles(this).get(roleName); + if (role == null) { + Log.w(LOG_TAG, "Unknown role: " + roleName); + finish(); + return; + } + + if (PackageUtils.getApplicationInfo(packageName, this) == null) { + Log.w(LOG_TAG, "Unknown application: " + packageName); + finish(); + return; + } + + RoleManager roleManager = getSystemService(RoleManager.class); + List currentPackageNames = roleManager.getRoleHolders(roleName); + if (currentPackageNames.contains(packageName)) { + Log.i(LOG_TAG, "Application is already a role holder, role: " + roleName + + ", application: " + packageName); + setResult(RESULT_OK); + finish(); + return; + } + + if (!role.isPackageQualified(packageName, this)) { + Log.w(LOG_TAG, "Application doesn't qualify for role, role: " + roleName + + ", application: " + packageName); + finish(); + return; + } + + // TODO: STOPSHIP: Handle other form factors. + if (savedInstanceState == null) { + RequestRoleFragment fragment = RequestRoleFragment.newInstance( + roleName, packageName); + getSupportFragmentManager().beginTransaction() + .replace(android.R.id.content, fragment) + .commit(); + } + } + + @Override + public void onBackPressed() { + // Don't allow back. + // TODO: STOPSHIP: Or do we allow? + } +} diff --git a/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java b/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java new file mode 100644 index 000000000..ee9bc3d55 --- /dev/null +++ b/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.packageinstaller.role.ui; + +import android.app.Activity; +import android.app.Dialog; +import android.app.role.RoleManager; +import android.app.role.RoleManagerCallback; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ApplicationInfo; +import android.os.Bundle; +import android.os.UserHandle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; +import androidx.fragment.app.DialogFragment; + +import com.android.packageinstaller.permission.utils.PackageRemovalMonitor; +import com.android.packageinstaller.permission.utils.Utils; +import com.android.packageinstaller.role.model.Role; +import com.android.packageinstaller.role.model.Roles; +import com.android.packageinstaller.role.utils.PackageUtils; +import com.android.permissioncontroller.R; + +import java.util.List; +import java.util.concurrent.Executor; + +/** + * {@code Fragment} for a role request. + */ +public class RequestRoleFragment extends DialogFragment { + + private static final String LOG_TAG = RequestRoleFragment.class.getSimpleName(); + + private String mRoleName; + private String mPackageName; + + @Nullable + private PackageRemovalMonitor mPackageRemovalMonitor; + + /** + * Create a new instance of this fragment. + * + * @param roleName the name of the requested role + * @param packageName the package name of the application requesting the role + * + * @return a new instance of this fragment + */ + public static RequestRoleFragment newInstance(@NonNull String roleName, + @NonNull String packageName) { + RequestRoleFragment instance = new RequestRoleFragment(); + Bundle arguments = new Bundle(); + arguments.putString(RoleManager.EXTRA_REQUEST_ROLE_NAME, roleName); + arguments.putString(Intent.EXTRA_PACKAGE_NAME, packageName); + instance.setArguments(arguments); + return instance; + } + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + Bundle arguments = getArguments(); + mPackageName = arguments.getString(Intent.EXTRA_PACKAGE_NAME); + mRoleName = arguments.getString(RoleManager.EXTRA_REQUEST_ROLE_NAME); + } + + @NonNull + @Override + public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { + Context context = requireContext(); + Role role = Roles.getRoles(context).get(mRoleName); + if (role == null) { + Log.w(LOG_TAG, "Unknown role: " + mRoleName); + finish(); + return super.onCreateDialog(savedInstanceState); + } + // FIXME: STOPSHIP: Add a label for role. + String roleLabel = role.getName(); + + ApplicationInfo applicationInfo = PackageUtils.getApplicationInfo(mPackageName, context); + if (applicationInfo == null) { + Log.w(LOG_TAG, "Unknown application: " + mPackageName); + finish(); + return super.onCreateDialog(savedInstanceState); + } + String applicationLabel = Utils.getAppLabel(applicationInfo, context); + + RoleManager roleManager = context.getSystemService(RoleManager.class); + List currentPackageNames = roleManager.getRoleHolders(mRoleName); + if (currentPackageNames.contains(mPackageName)) { + Log.i(LOG_TAG, "Application is already a role holder, role: " + mRoleName + + ", application: " + mPackageName); + setResultOkAndFinish(); + return super.onCreateDialog(savedInstanceState); + } + String currentApplicationLabel = role.isExclusive() ? getCurrentApplicationLabel( + currentPackageNames, context) : null; + + String message; + if (currentApplicationLabel == null) { + message = getString(R.string.role_request_message_add, applicationLabel, roleLabel); + } else { + message = getString(R.string.role_request_message_replace, applicationLabel, + currentApplicationLabel, roleLabel); + } + + return new AlertDialog.Builder(context, getTheme()) + .setMessage(message) + .setPositiveButton(android.R.string.ok, (dialog, which) -> addRoleHolder()) + .setNegativeButton(android.R.string.cancel, (dialog, which) -> finish()) + .create(); + } + + @Override + public void onStart() { + super.onStart(); + + mPackageRemovalMonitor = new PackageRemovalMonitor(requireContext(), mPackageName) { + @Override + protected void onPackageRemoved() { + finish(); + } + }; + mPackageRemovalMonitor.register(); + } + + @Override + public void onStop() { + super.onStop(); + + mPackageRemovalMonitor.unregister(); + mPackageRemovalMonitor = null; + } + + private void addRoleHolder() { + Log.i(LOG_TAG, "Adding package as role holder, role: " + mRoleName + ", package: " + + mPackageName); + Context context = requireContext(); + RoleManager roleManager = context.getSystemService(RoleManager.class); + UserHandle user = UserHandle.of(UserHandle.myUserId()); + Executor executor = context.getMainExecutor(); + roleManager.addRoleHolderAsUser(mRoleName, mPackageName, user, executor, + // TODO: Add progress or simply disable UI. + // FIXME: STOPSHIP: Leaking, and NPE! Use something like Loader or LiveData instead. + new RoleManagerCallback() { + @Override + public void onSuccess() { + Log.e(LOG_TAG, "Package added as role holder, role: " + mRoleName + + ", package: " + mPackageName); + setResultOkAndFinish(); + } + @Override + public void onFailure() { + Log.e(LOG_TAG, "Failed to add package as role holder, role: " + mRoleName + + ", package: " + mPackageName); + finish(); + } + }); + } + + private void setResultOkAndFinish() { + requireActivity().setResult(Activity.RESULT_OK); + finish(); + } + + private void finish() { + requireActivity().finish(); + } + + private static String getCurrentApplicationLabel(@NonNull List currentPackageNames, + @NonNull Context context) { + if (currentPackageNames.isEmpty()) { + return null; + } + String currentPackageName = currentPackageNames.get(0); + + ApplicationInfo currentApplicationInfo = PackageUtils.getApplicationInfo( + currentPackageName, context); + if (currentApplicationInfo == null) { + return null; + } + + return Utils.getAppLabel(currentApplicationInfo, context); + } +} diff --git a/src/com/android/packageinstaller/role/utils/Utils.java b/src/com/android/packageinstaller/role/utils/PackageUtils.java similarity index 94% rename from src/com/android/packageinstaller/role/utils/Utils.java rename to src/com/android/packageinstaller/role/utils/PackageUtils.java index 88df69524..d3fe999e7 100644 --- a/src/com/android/packageinstaller/role/utils/Utils.java +++ b/src/com/android/packageinstaller/role/utils/PackageUtils.java @@ -25,50 +25,50 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; /** - * Miscellaneous utility methods. + * Utility methods about application packages. */ -public final class Utils { +public final class PackageUtils { - private Utils() {} + private PackageUtils() {} /** - * Retrieve the {@link ApplicationInfo} of an application. + * Retrieve the {@link PackageInfo} of an application. * * @param packageName the package name of the application + * @param extraFlags the extra flags to pass to {@link PackageManager#getPackageInfo(String, + * int)} * @param context the {@code Context} to retrieve system services * - * @return the {@link ApplicationInfo} of the application, or {@code null} if not found. + * @return the {@link PackageInfo} of the application, or {@code null} if not found */ @Nullable - public static ApplicationInfo getApplicationInfo(@NonNull String packageName, + public static PackageInfo getPackageInfo(@NonNull String packageName, int extraFlags, @NonNull Context context) { PackageManager packageManager = context.getPackageManager(); try { - return packageManager.getApplicationInfo(packageName, - PackageManager.MATCH_DIRECT_BOOT_AWARE - | PackageManager.MATCH_DIRECT_BOOT_UNAWARE); + return packageManager.getPackageInfo(packageName, PackageManager.MATCH_DIRECT_BOOT_AWARE + | PackageManager.MATCH_DIRECT_BOOT_UNAWARE | extraFlags); } catch (PackageManager.NameNotFoundException e) { return null; } } /** - * Retrieve the {@link PackageInfo} of an application. + * Retrieve the {@link ApplicationInfo} of an application. * * @param packageName the package name of the application - * @param extraFlags the extra flags to pass to {@link PackageManager#getPackageInfo(String, - * int)} * @param context the {@code Context} to retrieve system services * - * @return the {@link PackageInfo} of the application, or {@code null} if not found. + * @return the {@link ApplicationInfo} of the application, or {@code null} if not found */ @Nullable - public static PackageInfo getPackageInfo(@NonNull String packageName, int extraFlags, + public static ApplicationInfo getApplicationInfo(@NonNull String packageName, @NonNull Context context) { PackageManager packageManager = context.getPackageManager(); try { - return packageManager.getPackageInfo(packageName, PackageManager.MATCH_DIRECT_BOOT_AWARE - | PackageManager.MATCH_DIRECT_BOOT_UNAWARE | extraFlags); + return packageManager.getApplicationInfo(packageName, + PackageManager.MATCH_DIRECT_BOOT_AWARE + | PackageManager.MATCH_DIRECT_BOOT_UNAWARE); } catch (PackageManager.NameNotFoundException e) { return null; } -- GitLab From 4b7f5b9ab0cfd35de99070bda1cad6a0393a64d8 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Mon, 12 Nov 2018 14:31:35 -0800 Subject: [PATCH 128/701] Fix typo preventing PermissionApps screen from opening. The condition is inverted, which means that the MANAGE_PERMISSION_APPS intent cannot launch PermissionAppsFragment. Test: Opened the permission apps screen. Change-Id: I9007c75de839a859c94c5da9208f14a5ee53aacc --- .../permission/ui/ManagePermissionsActivity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/android/packageinstaller/permission/ui/ManagePermissionsActivity.java b/src/com/android/packageinstaller/permission/ui/ManagePermissionsActivity.java index 379e9320e..20b668e29 100644 --- a/src/com/android/packageinstaller/permission/ui/ManagePermissionsActivity.java +++ b/src/com/android/packageinstaller/permission/ui/ManagePermissionsActivity.java @@ -102,7 +102,7 @@ public final class ManagePermissionsActivity extends FragmentActivity { permissionName = verifyIntent(this, getIntent()); // fall through case Intent.ACTION_MANAGE_PERMISSION_APPS: { - if (permissionName != null) { + if (permissionName == null) { permissionName = getIntent().getStringExtra(Intent.EXTRA_PERMISSION_NAME); } -- GitLab From a5c8f55c861d1a33a81bc3b07f37e04270e4e711 Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Mon, 12 Nov 2018 17:16:14 -0800 Subject: [PATCH 129/701] Use LiveData for adding a role holder in role request. Due to the async nature of role operations, we need an object to take care of the RoleManager.addRoleHolderAsUser() callback, keep track of the state while avoiding leaking a surrounding context. ViewModel and LiveData is a good fit for this scenario. Bug: 110557011 Test: build Change-Id: Id6ad1c92d7046ecfbc232ef0133b0566d4f7750c --- Android.mk | 2 + .../role/ui/RequestRoleActivity.java | 8 +- .../role/ui/RequestRoleFragment.java | 61 +++++++------- .../role/ui/RequestRoleLiveData.java | 84 +++++++++++++++++++ .../role/ui/RequestRoleViewModel.java | 34 ++++++++ 5 files changed, 157 insertions(+), 32 deletions(-) create mode 100644 src/com/android/packageinstaller/role/ui/RequestRoleLiveData.java create mode 100644 src/com/android/packageinstaller/role/ui/RequestRoleViewModel.java diff --git a/Android.mk b/Android.mk index 1b9f413c1..90675fba2 100644 --- a/Android.mk +++ b/Android.mk @@ -23,6 +23,8 @@ LOCAL_STATIC_ANDROID_LIBRARIES += \ androidx.legacy_legacy-preference-v14 \ androidx.leanback_leanback \ androidx.leanback_leanback-preference \ + androidx.lifecycle_lifecycle-extensions \ + androidx.lifecycle_lifecycle-common-java8 \ SettingsLibHelpUtils \ SettingsLibRestrictedLockUtils \ SettingsLibAppPreference \ diff --git a/src/com/android/packageinstaller/role/ui/RequestRoleActivity.java b/src/com/android/packageinstaller/role/ui/RequestRoleActivity.java index 405f3cda4..e739f14db 100644 --- a/src/com/android/packageinstaller/role/ui/RequestRoleActivity.java +++ b/src/com/android/packageinstaller/role/ui/RequestRoleActivity.java @@ -77,16 +77,16 @@ public class RequestRoleActivity extends FragmentActivity { RoleManager roleManager = getSystemService(RoleManager.class); List currentPackageNames = roleManager.getRoleHolders(roleName); if (currentPackageNames.contains(packageName)) { - Log.i(LOG_TAG, "Application is already a role holder, role: " + roleName - + ", application: " + packageName); + Log.i(LOG_TAG, "Application is already a role holder, role: " + roleName + ", package: " + + packageName); setResult(RESULT_OK); finish(); return; } if (!role.isPackageQualified(packageName, this)) { - Log.w(LOG_TAG, "Application doesn't qualify for role, role: " + roleName - + ", application: " + packageName); + Log.w(LOG_TAG, "Application doesn't qualify for role, role: " + roleName + ", package: " + + packageName); finish(); return; } diff --git a/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java b/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java index ee9bc3d55..a2bf2d497 100644 --- a/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java +++ b/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java @@ -19,18 +19,17 @@ package com.android.packageinstaller.role.ui; import android.app.Activity; import android.app.Dialog; import android.app.role.RoleManager; -import android.app.role.RoleManagerCallback; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.os.Bundle; -import android.os.UserHandle; import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.DialogFragment; +import androidx.lifecycle.ViewModelProviders; import com.android.packageinstaller.permission.utils.PackageRemovalMonitor; import com.android.packageinstaller.permission.utils.Utils; @@ -40,7 +39,6 @@ import com.android.packageinstaller.role.utils.PackageUtils; import com.android.permissioncontroller.R; import java.util.List; -import java.util.concurrent.Executor; /** * {@code Fragment} for a role request. @@ -52,7 +50,8 @@ public class RequestRoleFragment extends DialogFragment { private String mRoleName; private String mPackageName; - @Nullable + private RequestRoleViewModel mViewModel; + private PackageRemovalMonitor mPackageRemovalMonitor; /** @@ -107,7 +106,7 @@ public class RequestRoleFragment extends DialogFragment { List currentPackageNames = roleManager.getRoleHolders(mRoleName); if (currentPackageNames.contains(mPackageName)) { Log.i(LOG_TAG, "Application is already a role holder, role: " + mRoleName - + ", application: " + mPackageName); + + ", package: " + mPackageName); setResultOkAndFinish(); return super.onCreateDialog(savedInstanceState); } @@ -129,6 +128,14 @@ public class RequestRoleFragment extends DialogFragment { .create(); } + @Override + public void onActivityCreated(@Nullable Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + mViewModel = ViewModelProviders.of(this).get(RequestRoleViewModel.class); + mViewModel.getLiveData().observe(this, this::onRequestRoleStateChanged); + } + @Override public void onStart() { super.onStart(); @@ -150,30 +157,28 @@ public class RequestRoleFragment extends DialogFragment { mPackageRemovalMonitor = null; } + private void onRequestRoleStateChanged(int state) { + AlertDialog dialog = (AlertDialog) getDialog(); + switch (state) { + case RequestRoleLiveData.STATE_IDLE: + dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(true); + dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setEnabled(true); + break; + case RequestRoleLiveData.STATE_ADDING: + dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false); + dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setEnabled(false); + break; + case RequestRoleLiveData.STATE_SUCCESS: + setResultOkAndFinish(); + break; + case RequestRoleLiveData.STATE_FAILURE: + finish(); + break; + } + } + private void addRoleHolder() { - Log.i(LOG_TAG, "Adding package as role holder, role: " + mRoleName + ", package: " - + mPackageName); - Context context = requireContext(); - RoleManager roleManager = context.getSystemService(RoleManager.class); - UserHandle user = UserHandle.of(UserHandle.myUserId()); - Executor executor = context.getMainExecutor(); - roleManager.addRoleHolderAsUser(mRoleName, mPackageName, user, executor, - // TODO: Add progress or simply disable UI. - // FIXME: STOPSHIP: Leaking, and NPE! Use something like Loader or LiveData instead. - new RoleManagerCallback() { - @Override - public void onSuccess() { - Log.e(LOG_TAG, "Package added as role holder, role: " + mRoleName - + ", package: " + mPackageName); - setResultOkAndFinish(); - } - @Override - public void onFailure() { - Log.e(LOG_TAG, "Failed to add package as role holder, role: " + mRoleName - + ", package: " + mPackageName); - finish(); - } - }); + mViewModel.getLiveData().addRoleHolder(mRoleName, mPackageName, requireContext()); } private void setResultOkAndFinish() { diff --git a/src/com/android/packageinstaller/role/ui/RequestRoleLiveData.java b/src/com/android/packageinstaller/role/ui/RequestRoleLiveData.java new file mode 100644 index 000000000..42c0b472c --- /dev/null +++ b/src/com/android/packageinstaller/role/ui/RequestRoleLiveData.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.packageinstaller.role.ui; + +import android.app.role.RoleManager; +import android.app.role.RoleManagerCallback; +import android.content.Context; +import android.os.UserHandle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.lifecycle.LiveData; + +import java.util.concurrent.Executor; + +/** + * {@link LiveData} for the state of a role request. + */ +public class RequestRoleLiveData extends LiveData { + + private static final String LOG_TAG = RequestRoleLiveData.class.getSimpleName(); + + public static final int STATE_IDLE = 0; + public static final int STATE_ADDING = 1; + public static final int STATE_SUCCESS = 2; + public static final int STATE_FAILURE = 3; + + public RequestRoleLiveData() { + setValue(STATE_IDLE); + } + + /** + * Add an application to the holders of a role, and update the state accordingly. Will be no-op + * if already called once. + * + * @param roleName the name of the role + * @param packageName the package name of the application + * @param context the {@code Context} to retrieve system services + */ + public void addRoleHolder(@NonNull String roleName, @NonNull String packageName, + @NonNull Context context) { + if (getValue() != STATE_IDLE) { + Log.w(LOG_TAG, "Already (tried) adding package as role holder, requested role: " + + roleName + ", requested package: " + packageName); + return; + } + Log.i(LOG_TAG, "Adding package as role holder, role: " + roleName + ", package: " + + packageName); + setValue(STATE_ADDING); + + RoleManager roleManager = context.getSystemService(RoleManager.class); + UserHandle user = UserHandle.of(UserHandle.myUserId()); + Executor executor = context.getMainExecutor(); + roleManager.addRoleHolderAsUser(roleName, packageName, user, executor, + new RoleManagerCallback() { + @Override + public void onSuccess() { + Log.i(LOG_TAG, "Package added as role holder, role: " + roleName + + ", package: " + packageName); + setValue(STATE_SUCCESS); + } + @Override + public void onFailure() { + Log.i(LOG_TAG, "Failed to add package as role holder, role: " + roleName + + ", package: " + packageName); + setValue(STATE_FAILURE); + } + }); + } +} diff --git a/src/com/android/packageinstaller/role/ui/RequestRoleViewModel.java b/src/com/android/packageinstaller/role/ui/RequestRoleViewModel.java new file mode 100644 index 000000000..6ebc7faaa --- /dev/null +++ b/src/com/android/packageinstaller/role/ui/RequestRoleViewModel.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.packageinstaller.role.ui; + +import androidx.annotation.NonNull; +import androidx.lifecycle.ViewModel; + +/** + * {@link ViewModel} for a role request. + */ +public class RequestRoleViewModel extends ViewModel { + + @NonNull + private RequestRoleLiveData mLiveData = new RequestRoleLiveData(); + + @NonNull + public RequestRoleLiveData getLiveData() { + return mLiveData; + } +} -- GitLab From ce1a9b4730e8022a7cf0f82028229ba6298044c9 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Tue, 13 Nov 2018 00:04:26 -0800 Subject: [PATCH 130/701] Import translations. DO NOT MERGE Change-Id: I986467b022772cdaea74dcb7b6e24079f30ebdd4 Auto-generated-cl: translation import --- res/values-af/strings.xml | 2 ++ res/values-am/strings.xml | 2 ++ res/values-ar/strings.xml | 2 ++ res/values-as/strings.xml | 5 +++-- res/values-az/strings.xml | 2 ++ res/values-b+sr+Latn/strings.xml | 2 ++ res/values-be/strings.xml | 2 ++ res/values-bg/strings.xml | 2 ++ res/values-bn/strings.xml | 2 ++ res/values-bs/strings.xml | 2 ++ res/values-ca/strings.xml | 2 ++ res/values-cs/strings.xml | 2 ++ res/values-da/strings.xml | 2 ++ res/values-de/strings.xml | 2 ++ res/values-el/strings.xml | 2 ++ res/values-en-rAU/strings.xml | 2 ++ res/values-en-rCA/strings.xml | 2 ++ res/values-en-rGB/strings.xml | 2 ++ res/values-en-rIN/strings.xml | 2 ++ res/values-en-rXC/strings.xml | 2 ++ res/values-es-rUS/strings.xml | 2 ++ res/values-es/strings.xml | 2 ++ res/values-et/strings.xml | 2 ++ res/values-eu/strings.xml | 2 ++ res/values-fa/strings.xml | 2 ++ res/values-fi/strings.xml | 2 ++ res/values-fr-rCA/strings.xml | 2 ++ res/values-fr/strings.xml | 2 ++ res/values-gl/strings.xml | 2 ++ res/values-gu/strings.xml | 2 ++ res/values-hi/strings.xml | 2 ++ res/values-hr/strings.xml | 2 ++ res/values-hu/strings.xml | 2 ++ res/values-hy/strings.xml | 2 ++ res/values-in/strings.xml | 2 ++ res/values-is/strings.xml | 2 ++ res/values-it/strings.xml | 2 ++ res/values-iw/strings.xml | 2 ++ res/values-ja/strings.xml | 2 ++ res/values-ka/strings.xml | 2 ++ res/values-kk/strings.xml | 2 ++ res/values-km/strings.xml | 2 ++ res/values-kn/strings.xml | 2 ++ res/values-ko/strings.xml | 2 ++ res/values-ky/strings.xml | 2 ++ res/values-lo/strings.xml | 2 ++ res/values-lt/strings.xml | 2 ++ res/values-lv/strings.xml | 2 ++ res/values-mk/strings.xml | 2 ++ res/values-ml/strings.xml | 5 +++-- res/values-mn/strings.xml | 2 ++ res/values-mr/strings.xml | 2 ++ res/values-ms/strings.xml | 2 ++ res/values-my/strings.xml | 2 ++ res/values-nb/strings.xml | 2 ++ res/values-ne/strings.xml | 5 +++-- res/values-nl/strings.xml | 2 ++ res/values-or/strings.xml | 5 +++-- res/values-pa/strings.xml | 2 ++ res/values-pl/strings.xml | 2 ++ res/values-pt-rBR/strings.xml | 2 ++ res/values-pt-rPT/strings.xml | 2 ++ res/values-pt/strings.xml | 2 ++ res/values-ro/strings.xml | 2 ++ res/values-ru/strings.xml | 2 ++ res/values-si/strings.xml | 5 +++-- res/values-sk/strings.xml | 2 ++ res/values-sl/strings.xml | 2 ++ res/values-sq/strings.xml | 2 ++ res/values-sr/strings.xml | 2 ++ res/values-sv/strings.xml | 2 ++ res/values-sw/strings.xml | 2 ++ res/values-ta/strings.xml | 5 +++-- res/values-te/strings.xml | 5 +++-- res/values-th/strings.xml | 2 ++ res/values-tl/strings.xml | 2 ++ res/values-tr/strings.xml | 2 ++ res/values-uk/strings.xml | 2 ++ res/values-ur/strings.xml | 2 ++ res/values-uz/strings.xml | 2 ++ res/values-vi/strings.xml | 2 ++ res/values-zh-rCN/strings.xml | 2 ++ res/values-zh-rHK/strings.xml | 2 ++ res/values-zh-rTW/strings.xml | 2 ++ res/values-zu/strings.xml | 2 ++ 85 files changed, 177 insertions(+), 14 deletions(-) diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml index 3572b7b63..ec4e60396 100644 --- a/res/values-af/strings.xml +++ b/res/values-af/strings.xml @@ -93,6 +93,8 @@ "Afgelope 1 uur" "Afgelope 15 minute" "Geen toestemminggebruike nie" + "Programtoestemmingsgebruik" + "%1$s gelede" %s dae 1 dag diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml index 1f7427059..fc60af44b 100644 --- a/res/values-am/strings.xml +++ b/res/values-am/strings.xml @@ -93,6 +93,8 @@ "ባለፈው 1 ሰዓት" "ባለፉት 15 ደቂቃዎች" "ምንም ፈቃድ አጠቃቀሞች የሉም" + "የመተግበሪያ ፈቃዶች አጠቃቀም" + "ከ%1$s በፊት" %s ቀኖች %s ቀኖች diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml index 5c0d220e8..3b1c25b21 100644 --- a/res/values-ar/strings.xml +++ b/res/values-ar/strings.xml @@ -97,6 +97,8 @@ "آخر ساعة" "آخر 15 دقيقة" "لم يتمّ استخدام الأذونات" + "استخدام أذونات التطبيق" + "قبل %1$s" %s يوم يومان (%s) diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml index 143e55c5c..04c25fe61 100644 --- a/res/values-as/strings.xml +++ b/res/values-as/strings.xml @@ -86,14 +86,15 @@ "অজ্ঞাত" "অনুমতিৰ ব্যৱহাৰ" "%1$s - %2$s আগত" - - + "যিকোনো অনুমতি" "যিকোনো সময়ত" "যোৱা ৭ দিনত" "যোৱা ২৪ ঘণ্টাত" "যোৱা ১ ঘণ্টাত" "যোৱা ১৫ মিনিটত" "অনুমতি ব্যৱহাৰ কৰা হোৱা নাই" + "এপৰ অনুমতিৰ ব্যৱহাৰ" + "%1$s আগত" %s দিন %s দিন diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml index 2d2b42417..e9c2f2c28 100644 --- a/res/values-az/strings.xml +++ b/res/values-az/strings.xml @@ -93,6 +93,8 @@ "Son 1 saat" "Son 15 dəqiqə" "İcazələrdən istifadə olunmayıb" + "Tətbiq icazələri istifadəsi" + "%1$s əvvəl" %s gün 1 gün diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml index 52b0dde32..930587d21 100644 --- a/res/values-b+sr+Latn/strings.xml +++ b/res/values-b+sr+Latn/strings.xml @@ -94,6 +94,8 @@ "Poslednji sat" "Poslednjih 15 minuta" "Dozvole nisu korišćene" + "Korišćenje dozvola za aplik." + "pre %1$s" %s dan %s dana diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml index 111e84526..30487d8e9 100644 --- a/res/values-be/strings.xml +++ b/res/values-be/strings.xml @@ -95,6 +95,8 @@ "За апошнюю гадзіну" "За апошнія 15 хвілін" "Без выкарыстання дазволаў" + "Выкарыстанне дазволаў праграмы" + "%1$s таму назад" %s дзень %s дні diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml index fa1fdae8b..db2f4b92f 100644 --- a/res/values-bg/strings.xml +++ b/res/values-bg/strings.xml @@ -93,6 +93,8 @@ "Последният 1 час" "Последните 15 минути" "Разрешенията не са използвани" + "Използване на разрешенията" + "Преди %1$s" %s дни 1 ден diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml index 69a8f7464..68483925f 100644 --- a/res/values-bn/strings.xml +++ b/res/values-bn/strings.xml @@ -93,6 +93,8 @@ "শেষ ১ ঘণ্টা" "গত ১৫ মিনিট" "কোন অনুমতির ব্যবহার হয়নি" + "অ্যাপের অনুমতির ব্যবহার" + "%1$s আগে" %s দিন %s দিন diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml index 9d3f13690..782990945 100644 --- a/res/values-bs/strings.xml +++ b/res/values-bs/strings.xml @@ -94,6 +94,8 @@ "Posljednji sat" "Posljednjih 15 minuta" "Odobrenje nije upotrijebljeno" + "Korišt. dozvole za aplikacije" + "Prije %1$s" %s dan %s dana diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml index 8f69870f8..1625c1b1a 100644 --- a/res/values-ca/strings.xml +++ b/res/values-ca/strings.xml @@ -93,6 +93,8 @@ "Última hora" "Últims 15 minuts" "Cap ús de permisos" + "Ús de permisos de l\'aplicació" + "Fa %1$s" %s dies 1 dia diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml index 7a51613b9..4376d9049 100644 --- a/res/values-cs/strings.xml +++ b/res/values-cs/strings.xml @@ -95,6 +95,8 @@ "Poslední hodina" "Posledních 15 minut" "Žádné využití oprávnění" + "Využití oprávnění aplikace" + "Před %1$s" %s dny %s dne diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml index 50ea68a8e..3004a7733 100644 --- a/res/values-da/strings.xml +++ b/res/values-da/strings.xml @@ -93,6 +93,8 @@ "Den seneste time" "De seneste 15 minutter" "Ingen brug af tilladelsen" + "Brug af apptilladelser" + "For %1$s siden" %s dag %s dage diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index 8141d101e..a6e65fdd6 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -93,6 +93,8 @@ "Letzte Stunde" "Letzte 15 Minuten" "Keine Berechtigungen verwendet" + "Nutzung von App-Berechtigungen" + "vor %1$s" %s Tage 1 Tag diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml index f6ed7dc88..3f0a47264 100644 --- a/res/values-el/strings.xml +++ b/res/values-el/strings.xml @@ -93,6 +93,8 @@ "Τελευταία 1 ώρα" "Τελευταία 15 λεπτά" "Καμία χρήση δικαιωμάτων" + "Χρήση αδειών εφαρμογής" + "%1$s πριν" %s ημέρες 1 ημέρα diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml index 714fb7231..d79ad9e46 100644 --- a/res/values-en-rAU/strings.xml +++ b/res/values-en-rAU/strings.xml @@ -93,6 +93,8 @@ "Last 1 hour" "Last 15 minutes" "No permission usages" + "App permissions usage" + "%1$s ago" %s days 1 day diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml index 714fb7231..d79ad9e46 100644 --- a/res/values-en-rCA/strings.xml +++ b/res/values-en-rCA/strings.xml @@ -93,6 +93,8 @@ "Last 1 hour" "Last 15 minutes" "No permission usages" + "App permissions usage" + "%1$s ago" %s days 1 day diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml index 714fb7231..d79ad9e46 100644 --- a/res/values-en-rGB/strings.xml +++ b/res/values-en-rGB/strings.xml @@ -93,6 +93,8 @@ "Last 1 hour" "Last 15 minutes" "No permission usages" + "App permissions usage" + "%1$s ago" %s days 1 day diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml index 714fb7231..d79ad9e46 100644 --- a/res/values-en-rIN/strings.xml +++ b/res/values-en-rIN/strings.xml @@ -93,6 +93,8 @@ "Last 1 hour" "Last 15 minutes" "No permission usages" + "App permissions usage" + "%1$s ago" %s days 1 day diff --git a/res/values-en-rXC/strings.xml b/res/values-en-rXC/strings.xml index dd32597c1..2beaa76c0 100644 --- a/res/values-en-rXC/strings.xml +++ b/res/values-en-rXC/strings.xml @@ -93,6 +93,8 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‎‏‎‏‏‎‏‎‎‏‎‎‏‎‎‏‏‎‎‎‎‏‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‎‎‎‎‏‏‏‏‎‏‏‎‎‏‏‎‎‏‏‎Last 1 hour‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‏‎‏‏‏‎‎‎‏‎‏‏‎‏‎‎‎‏‏‎‎‎‎‎‎‎‏‏‎‎‎‎‎‏‎‎‏‏‎‏‎‎‏‎‎‏‎‏‎‎‎‎Last 15 minutes‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‏‎‏‏‎‎‏‎‏‏‎‏‏‎‎‎‎‎‏‏‏‎‎‎‎‏‎‎‎‎‏‏‎‏‏‏‎‏‎‏‎‎‏‏‎‏‏‎‏‏‎‏‏‎‏‏‎No permission usages‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‏‎‎‎‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‏‏‎‏‎‏‎‎‏‏‎‎‎‏‏‎‎‏‏‏‎‏‎‏‎‏‎‎‏‏‏‏‎‎App permissions usage‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‏‎‎‏‏‏‎‎‎‏‎‏‎‎‎‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‏‎‎‎‏‏‏‎‎‏‎‏‏‎‎‏‏‎‎‎‏‎‏‏‏‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ ago‎‏‎‎‏‎" ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‎‎‏‎‏‎‏‏‏‎‏‏‏‎‏‏‎‎‏‎‏‏‎‎‎‏‎‎‏‏‏‏‎‎‏‏‎‎‏‏‏‏‎‎‎‏‏‎‎‎‎‎‎‎‏‏‎‎‏‎‎‏‏‎%s‎‏‎‎‏‏‏‎ days‎‏‎‎‏‎ ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‎‎‏‎‏‎‏‏‏‎‏‏‏‎‏‏‎‎‏‎‏‏‎‎‎‏‎‎‏‏‏‏‎‎‏‏‎‎‏‏‏‏‎‎‎‏‏‎‎‎‎‎‎‎‏‏‎1 day‎‏‎‎‏‎ diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml index 9405c4bb7..ae2283756 100644 --- a/res/values-es-rUS/strings.xml +++ b/res/values-es-rUS/strings.xml @@ -93,6 +93,8 @@ "Última hora" "Últimos 15 minutos" "Ningún uso de permisos" + "Uso de permisos de la app" + "Hace %1$s" %s días 1 día diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index b9ca025d7..05650af2d 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -93,6 +93,8 @@ "Última hora" "Últimos 15 minutos" "No se han usado los permisos" + "Uso permisos de la aplicación" + "Hace %1$s" %s días 1 día diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml index d663d85d0..8371f73cf 100644 --- a/res/values-et/strings.xml +++ b/res/values-et/strings.xml @@ -93,6 +93,8 @@ "Viimane tund" "Viimased 15 minutit" "Lube pole kasutatud" + "Rakenduse lubade kasutus" + "%1$s tagasi" %s päeva 1 päev diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml index 436d0d04b..f837f177a 100644 --- a/res/values-eu/strings.xml +++ b/res/values-eu/strings.xml @@ -93,6 +93,8 @@ "Azken orduan" "Azken 15 minutuetan" "Ez da eskatu baimenik" + "Aplikazio-baimenen erabilera" + "Duela %1$s" %s egun 1 egun diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml index c9521aa7e..dce46d937 100644 --- a/res/values-fa/strings.xml +++ b/res/values-fa/strings.xml @@ -93,6 +93,8 @@ "۱ ساعت اخیر" "۱۵ دقیقه اخیر" "هیچ مجوزی استفاده نشده است" + "استفاده از مجوزهای برنامه" + "%1$s قبل" %s روز %s روز diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml index 2f28ec7a4..2a9eebcad 100644 --- a/res/values-fi/strings.xml +++ b/res/values-fi/strings.xml @@ -93,6 +93,8 @@ "Viimeisin tunti" "Viimeiset 15 minuuttia" "Käyttöoikeuksia ei käytetty" + "Sovelluksen käyttöoikeudet" + "%1$s sitten" %s päivää 1 päivä diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml index 3d41ce4f0..65ddcd25e 100644 --- a/res/values-fr-rCA/strings.xml +++ b/res/values-fr-rCA/strings.xml @@ -93,6 +93,8 @@ "La dernière heure" "Les 15 dernières minutes" "Aucune autoris. d\'utilisation" + "Util. des autoris. de l\'appli" + "Il y a %1$s" %s jour %s jours diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index 5dc8320c0..73a4cb01a 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -93,6 +93,8 @@ "Dernière heure" "15 dernières minutes" "Aucune autorisation utilisée" + "Utilisation des autorisations" + "Il y a %1$s" %s jour %s jours diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml index 89e4b7c04..193544376 100644 --- a/res/values-gl/strings.xml +++ b/res/values-gl/strings.xml @@ -93,6 +93,8 @@ "Última hora" "Últimos 15 minutos" "Non se utilizaron os permisos" + "Uso dos permisos da aplicación" + "Hai %1$s" %s días 1 día diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml index 0052fc1c5..bcf37370d 100644 --- a/res/values-gu/strings.xml +++ b/res/values-gu/strings.xml @@ -93,6 +93,8 @@ "છેલ્લો 1 કલાક" "છેલ્લી 15 મિનિટ" "પરવાનગીનો ઉપયોગ થયો નથી" + "અ‍ૅપ પરવાનગીઓનો ઉપયોગ" + "%1$s પહેલાં" %s દિવસ %s દિવસ diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml index c34f82737..3d1846aa1 100644 --- a/res/values-hi/strings.xml +++ b/res/values-hi/strings.xml @@ -93,6 +93,8 @@ "पिछले एक घंटे में" "पिछले 15 मिनट में" "अनुमति का इस्तेमाल नहीं हुआ" + "ऐप्लिकेशन अनुमतियों इस्तेमाल" + "%1$s पहले" %s दिन %s दिन diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml index a1d04fac1..bb5a9b960 100644 --- a/res/values-hr/strings.xml +++ b/res/values-hr/strings.xml @@ -94,6 +94,8 @@ "Posljednjih sat vremena" "Posljednjih 15 minuta" "Nema upotreba dopuštenja" + "Upotreba dopuštenja aplikacije" + "prije %1$s" %s dana %s dana diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml index dd708c754..93efd92b5 100644 --- a/res/values-hu/strings.xml +++ b/res/values-hu/strings.xml @@ -93,6 +93,8 @@ "Elmúlt 1 óra" "Elmúlt 15 perc" "Nincs engedélyhasználat" + "Alkalmazásengedély-használat" + "Ennyi idővel ezelőtt: %1$s" %s nap 1 nap diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml index 4f8df9e5a..c27926ee0 100644 --- a/res/values-hy/strings.xml +++ b/res/values-hy/strings.xml @@ -93,6 +93,8 @@ "Վերջին ժամում" "Վերջին 15 րոպեում" "Թույլտվություններ չեն կիրառվել" + "Թույլտվությունների օգտագործում" + "%1$s առաջ" %s օր %s օր diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml index 83a581beb..fc89a69b3 100644 --- a/res/values-in/strings.xml +++ b/res/values-in/strings.xml @@ -93,6 +93,8 @@ "1 jam terakhir" "15 menit terakhir" "Tidak ada penggunaan izin" + "Penggunaan izin aplikasi" + "%1$s yang lalu" %s hari 1 hari diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml index 7b9d1ef4c..2589e9736 100644 --- a/res/values-is/strings.xml +++ b/res/values-is/strings.xml @@ -93,6 +93,8 @@ "Síðustu klukkustund" "Síðustu 15 mínútur" "Engin heimildanotkun" + "Notkun heimilda forrits" + "fyrir %1$s" %s dagur %s dagar diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml index 9008c11cf..7e8134fd8 100644 --- a/res/values-it/strings.xml +++ b/res/values-it/strings.xml @@ -93,6 +93,8 @@ "Ultima ora" "Ultimi 15 minuti" "Autorizzazioni non usate" + "Uso delle autorizzazioni app" + "%1$s fa" %s giorni 1 giorno diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml index 340066112..5ff40136c 100644 --- a/res/values-iw/strings.xml +++ b/res/values-iw/strings.xml @@ -95,6 +95,8 @@ "בשעה האחרונה" "15 הדקות האחרונות" "אין שימוש בהרשאות" + "שימוש בהרשאות האפליקציה" + "לפני %1$s" יומיים (%s) %s ימים diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml index 658108553..7f15211e6 100644 --- a/res/values-ja/strings.xml +++ b/res/values-ja/strings.xml @@ -93,6 +93,8 @@ "過去 1 時間" "過去 15 分間" "権限の使用はなし" + "アプリの権限の使用" + "%1$s 前" %s 1日 diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml index b4c5857c9..86a90cdbc 100644 --- a/res/values-ka/strings.xml +++ b/res/values-ka/strings.xml @@ -93,6 +93,8 @@ "ბოლო 1 საათი" "ბოლო 15 წუთი" "ამ ნებართვებს აპები არ იყენებს" + "აპის ნებართვებით სარგებლობა" + "%1$sს წინ" %s დღე 1 დღე diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml index 4bea2a341..7aff68fdd 100644 --- a/res/values-kk/strings.xml +++ b/res/values-kk/strings.xml @@ -93,6 +93,8 @@ "Соңғы 1 сағат" "Соңғы 15 минут" "Рұқсаттар пайдаланылмаған" + "Қолданба рұқсаттарын пайдалану" + "%1$s бұрын" %s күн 1 күн diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml index 3f0bca52a..f41ec8a09 100644 --- a/res/values-km/strings.xml +++ b/res/values-km/strings.xml @@ -93,6 +93,8 @@ "1 ម៉ោង​ចុងក្រោយ" "15 នាទី​ចុងក្រោយ" "គ្មាន​ការប្រើប្រាស់​ការអនុញ្ញាត​ទេ" + "ការប្រើប្រាស់​ការអនុញ្ញាត​កម្មវិធី" + "%1$s មុន" %s ថ្ងៃ 1 ថ្ងៃ diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml index a2772625e..5e35d87d1 100644 --- a/res/values-kn/strings.xml +++ b/res/values-kn/strings.xml @@ -93,6 +93,8 @@ "1 ಗಂಟೆಯ ಹಿಂದೆ" "ಹಿಂದಿನ 15 ನಿಮಿಷಗಳು" "ಅನುಮತಿಯ ಬಳಕೆಗಳು ಇಲ್ಲ" + "ಆ್ಯಪ್‌ ಅನುಮತಿಗಳ ಬಳಕೆ" + "%1$s ನಿಮಿಷಗಳ ಹಿಂದೆ" %s ದಿನಗಳು %s ದಿನಗಳು diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml index 44df27dd5..c3f0b8a71 100644 --- a/res/values-ko/strings.xml +++ b/res/values-ko/strings.xml @@ -93,6 +93,8 @@ "최근 1시간" "지난 15분" "사용 권한 없음" + "앱 권한 사용" + "%1$s 전" %s 1일 diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml index 50a938505..6473de201 100644 --- a/res/values-ky/strings.xml +++ b/res/values-ky/strings.xml @@ -93,6 +93,8 @@ "Акыркы 1 саатта" "Акыркы 15 мүнөттө" "Уруксаттар колдонулган жок" + "Колдонмонун уруксаттарын пайдалануу" + "%1$s мурун" %s күн 1 күн diff --git a/res/values-lo/strings.xml b/res/values-lo/strings.xml index 12be4e68e..e5026a5f0 100644 --- a/res/values-lo/strings.xml +++ b/res/values-lo/strings.xml @@ -93,6 +93,8 @@ "1 ຊົ່ວໂມງທີ່ຜ່ານມາ" "15 ນາທີຜ່ານມາ" "ບໍ່ມີການນຳໃຊ້ສິດອະນຸຍາດ" + "ການໃຊ້ສິດອະນຸຍາດແອັບ" + "%1$s ກ່ອນ" %s ມື້ 1 ມື້ diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml index 7f3f81d15..e658b3a9b 100644 --- a/res/values-lt/strings.xml +++ b/res/values-lt/strings.xml @@ -95,6 +95,8 @@ "Pastaroji 1 valanda" "Pastarosios 15 minučių" "Leidimai nenaudoti" + "Programos leidimų naudojimas" + "Prieš %1$s" %s diena %s dienos diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml index e5c7b95d1..ce54dcb93 100644 --- a/res/values-lv/strings.xml +++ b/res/values-lv/strings.xml @@ -94,6 +94,8 @@ "Pēdējā stundā" "Pēdējās 15 minūtēs" "Nav lietota neviena atļauja" + "Lietotņu atļauju lietojums" + "Pirms %1$s" %s dienu %s diena diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml index 0266f75fc..bdb3bbdd2 100644 --- a/res/values-mk/strings.xml +++ b/res/values-mk/strings.xml @@ -93,6 +93,8 @@ "Последниов час" "Последните 15 минути" "Не се користени дозволи" + "Дозволи за апликација" + "Пред %1$s" %s ден %s дена diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml index d8ce9842b..ed48556cf 100644 --- a/res/values-ml/strings.xml +++ b/res/values-ml/strings.xml @@ -86,14 +86,15 @@ "അജ്ഞാതം" "അനുമതികളുടെ ഉപയോഗം" "%1$s - %2$s മുമ്പ്" - - + "ഏതെങ്കിലും അനുമതി" "ഏത് സമയത്തും" "കഴിഞ്ഞ 7 ദിവസം" "അവസാന 24 മണിക്കൂർ" "കഴിഞ്ഞ ഒരു മണിക്കൂര്‍‌" "കഴിഞ്ഞ 15 മിനിറ്റ്" "അനുമതി ഉപയോഗങ്ങളൊന്നുമില്ല" + "ആപ്പ് അനുമതികളുടെ ഉപയോഗം" + "%1$s മുമ്പ്" %s ദിവസം ഒരു ദിവസം diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml index 1fc5b9ae3..c5c302f19 100644 --- a/res/values-mn/strings.xml +++ b/res/values-mn/strings.xml @@ -93,6 +93,8 @@ "Сүүлийн 1 цаг" "Сүүлийн 15 минут" "Зөвшөөрлийн хэрэглээ алга" + "Аппын зөвшөөрлийн ашиглалт" + "%1$s-н өмнө" %s өдөр 1 өдөр diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml index 62000198b..432c9c858 100644 --- a/res/values-mr/strings.xml +++ b/res/values-mr/strings.xml @@ -93,6 +93,8 @@ "शेवटचा एक तास" "शेवटची १५ मिनिटे" "वापराची परवानगी नाही" + "अॅप परवानग्यांचा वापर" + "%1$s पूर्वी" %s दिवस %s दिवस diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml index ab944ddc8..c945ad0e8 100644 --- a/res/values-ms/strings.xml +++ b/res/values-ms/strings.xml @@ -93,6 +93,8 @@ "Sejam yang lalu" "15 minit yang lalu" "Tiada penggunaan kebenaran" + "Penggunaan kebenaran apl" + "%1$s yang lalu" %s hari 1 hari diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml index c19f92506..61cc790df 100644 --- a/res/values-my/strings.xml +++ b/res/values-my/strings.xml @@ -93,6 +93,8 @@ "ပြီးခဲ့သော ၁ နာရီ" "ပြီးခဲ့သော ၁၅ မိနစ်" "မည်သည့်ခွင့်ပြုချက်မှ မသုံးပါ" + "အက်ပ်ခွင့်ပြုချက် အသုံးပြုမှု" + "ပြီးခဲ့သည့် %1$s က" %s ရက် ၁ ရက် diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml index e45cb2e48..d6d80fba6 100644 --- a/res/values-nb/strings.xml +++ b/res/values-nb/strings.xml @@ -93,6 +93,8 @@ "Den siste timen" "De siste 15 minuttene" "Ingen bruk av tillatelsen" + "Bruk av apptillatelser" + "for %1$s siden" %s dager 1 dag diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml index dbe6bd82a..2d315611c 100644 --- a/res/values-ne/strings.xml +++ b/res/values-ne/strings.xml @@ -86,14 +86,15 @@ "अज्ञात" "अनुमतिको उपयोग" "%1$s - %2$s पहिले" - - + "कुनै पनि अनुमति" "कुनै पनि समय" "पछिल्ला ७ दिन" "पछिल्लो २४ घन्टा" "पछिल्लो १ घन्टा" "पछिल्लो १५ मिनेट" "उपयोगको अनुमति छैन" + "अनुप्रयोगको अनुमतिको उपयोग" + "%1$s पहिले" %s दिन १ दिन diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml index 859d26143..14e907c40 100644 --- a/res/values-nl/strings.xml +++ b/res/values-nl/strings.xml @@ -93,6 +93,8 @@ "Afgelopen uur" "Afgelopen 15 minuten" "Geen gebruik van machtigingen" + "Gebruik van app-machtigingen" + "%1$s geleden" %s dagen 1 dag diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml index 1b073d1a3..c70a806b0 100644 --- a/res/values-or/strings.xml +++ b/res/values-or/strings.xml @@ -86,14 +86,15 @@ "ଅଜଣା" "ବ୍ୟବହାର ପାଇଁ ଅନୁମତି" "%1$s - %2$s ପୂର୍ବେ" - - + "ଯେକୌଣସି ଅନୁମତି" "ଯେକୌଣସି ସମୟରେ" "ଗତ 7 ଦିନ" "ଶେଷ 24 ଘଣ୍ଟା" "ଶେଷ 1 ଘଣ୍ଟା" "ଶେଷ 15 ମିନିଟ୍" "ବ୍ୟବହାର ପାଇଁ କୌଣସି ଅନୁମତି ନାହିଁ" + "ଆପ୍‍ ଅନୁମତି ବ୍ୟବହାର" + "%1$s ପୂର୍ବେ" %s ଦିନ 1 ଦିନ diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml index c28abdd94..7150da0ac 100644 --- a/res/values-pa/strings.xml +++ b/res/values-pa/strings.xml @@ -93,6 +93,8 @@ "ਪਿਛਲਾ 1 ਘੰਟਾ" "ਪਿਛਲੇ 15 ਮਿੰਟ" "ਕੋਈ ਇਜਾਜ਼ਤ ਨਹੀਂ ਵਰਤੀ ਗਈ" + "ਐਪ ਇਜਾਜ਼ਤਾਂ ਵਰਤੋ" + "%1$s ਪਹਿਲਾਂ" %s ਦਿਨ %s ਦਿਨ diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml index 2c09520db..a4fcc3470 100644 --- a/res/values-pl/strings.xml +++ b/res/values-pl/strings.xml @@ -95,6 +95,8 @@ "Ostatnia godzina" "Ostatnie 15 minut" "Brak użycia uprawnień" + "Użycie uprawnień aplikacji" + "%1$s temu" %s dni %s dni diff --git a/res/values-pt-rBR/strings.xml b/res/values-pt-rBR/strings.xml index ee24e1a15..e193ebaad 100644 --- a/res/values-pt-rBR/strings.xml +++ b/res/values-pt-rBR/strings.xml @@ -93,6 +93,8 @@ "Última hora" "Últimos 15 minutos" "Nenhum uso de permissões" + "Uso de permissões do app" + "Há %1$s" %s dia %s dias diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml index 1b4a08143..ec8df84ff 100644 --- a/res/values-pt-rPT/strings.xml +++ b/res/values-pt-rPT/strings.xml @@ -93,6 +93,8 @@ "Última hora" "Últimos 15 minutos" "Autorizações não utilizadas" + "Utiliz. de autoriz. da app" + "Há %1$s" %s dias 1 dia diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml index ee24e1a15..e193ebaad 100644 --- a/res/values-pt/strings.xml +++ b/res/values-pt/strings.xml @@ -93,6 +93,8 @@ "Última hora" "Últimos 15 minutos" "Nenhum uso de permissões" + "Uso de permissões do app" + "Há %1$s" %s dia %s dias diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml index eabaaa0d6..d0396f88f 100644 --- a/res/values-ro/strings.xml +++ b/res/values-ro/strings.xml @@ -94,6 +94,8 @@ "Ultima oră" "Ultimele 15 minute" "Nicio permisiune folosită" + "Utilizare permisiuni pentru aplicație" + "Acum %1$s" %s zile %s de zile diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index 7189b1f3f..0cd641b19 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -95,6 +95,8 @@ "Последний час" "Последние 15 минут" "Разрешения не использовались" + "Использование разрешений" + "%1$s назад" %s день %s дня diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml index b51d2acc0..31fd8085b 100644 --- a/res/values-si/strings.xml +++ b/res/values-si/strings.xml @@ -86,14 +86,15 @@ "නොදනී" "අවසර භාවිතය" "%1$s - %2$s පෙර" - - + "ඕනෑම අවසරයක්" "ඕනෑම වේලාවක" "පසුගිය දින 7" "පසුගිය පැය 24" "පසුගිය පැය 1" "පසුගිය මිනිත්තු 15" "අවසර භාවිත නැත" + "යෙදුම් අවසර භාවිතය" + "%1$sකට පෙර" දින %s දින %s diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml index 9d60e7fc2..51a1b0c2e 100644 --- a/res/values-sk/strings.xml +++ b/res/values-sk/strings.xml @@ -95,6 +95,8 @@ "Posledná hodina" "Posledných 15 minút" "Žiadne využitie povolení" + "Využitie povolení aplikácie" + "pred %1$s" %s dni %s dňa diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml index 572f337c3..6e4ba2010 100644 --- a/res/values-sl/strings.xml +++ b/res/values-sl/strings.xml @@ -95,6 +95,8 @@ "Zadnja ura" "Zadnjih 15 minut" "Ni uporabe dovoljenj" + "Uporaba dovoljenj aplikacije" + "pred %1$s" %s dnevom %s dnevoma diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml index 2b07c6886..357fa615f 100644 --- a/res/values-sq/strings.xml +++ b/res/values-sq/strings.xml @@ -93,6 +93,8 @@ "1 orën e fundit" "15 minutat e fundit" "Nuk ka përdorime të lejeve" + "Përdorimi i lejeve të apl." + "%1$s më parë" %s ditë 1 ditë diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml index 58f4d0069..ff71a164c 100644 --- a/res/values-sr/strings.xml +++ b/res/values-sr/strings.xml @@ -94,6 +94,8 @@ "Последњи сат" "Последњих 15 минута" "Дозволе нису коришћене" + "Коришћење дозвола за аплик." + "пре %1$s" %s дан %s дана diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml index 103daa696..3106f31c5 100644 --- a/res/values-sv/strings.xml +++ b/res/values-sv/strings.xml @@ -93,6 +93,8 @@ "Senaste timmen" "De senaste 15 minuterna" "Ingen behörighetsanvändning" + "Appens behörighetsanvändning" + "För %1$s sedan" %s dagar 1 dag diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml index 8074ec844..b6e6589db 100644 --- a/res/values-sw/strings.xml +++ b/res/values-sw/strings.xml @@ -93,6 +93,8 @@ "Saa 1 iliyopita" "Dakika 15 zilizopita" "Hakuna matumizi ya ruhusa" + "Matumizi ya idhini za programu" + "%1$s zilizopita" Siku %s Siku 1 diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml index 881b4f8ba..eb53a7a54 100644 --- a/res/values-ta/strings.xml +++ b/res/values-ta/strings.xml @@ -86,14 +86,15 @@ "தெரியாதது" "அனுமதிகள் உபயோகம்" "%1$s - %2$sக்கு முன்பு" - - + "அனுமதி எதுவாயினும்" "எந்த நேரமும்" "கடந்த 7 நாட்கள்" "கடந்த 24 மணிநேரம்" "கடந்த ஒரு மணிநேரம்" "கடந்த 15 நிமிடங்கள்" "உபயோகிக்கப்படாத அனுமதிகள்" + "ஆப்ஸ் அனுமதிகளை உபயோகித்தல்" + "%1$s முன்பு" %s நாட்கள் 1 நாள் diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml index 9e5eea4c1..505783206 100644 --- a/res/values-te/strings.xml +++ b/res/values-te/strings.xml @@ -86,14 +86,15 @@ "తెలియదు" "అనుమతుల వినియోగం" "%1$s - %2$s క్రితం" - - + "ఏ అనుమతి అయినా" "ఎప్పుడైనా" "గత 7 రోజులు" "గత 24 గంటలు" "గత 1 గంట" "గత 15 నిమిషాలు" "అనుమతి వినియోగాలేవీ లేవు" + "యాప్ అనుమతుల వినియోగం" + "%1$s క్రితం" %s రోజులు 1 రోజు diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml index c55c2e4f8..6e4d6944f 100644 --- a/res/values-th/strings.xml +++ b/res/values-th/strings.xml @@ -93,6 +93,8 @@ "1 ชั่วโมงที่ผ่านมา" "15 นาทีที่ผ่านมา" "ไม่มีการใช้สิทธิ์" + "การใช้สิทธิ์ของแอป" + "%1$sที่ผ่านมา" %s วัน 1 วัน diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml index b4f93614d..11baf41e1 100644 --- a/res/values-tl/strings.xml +++ b/res/values-tl/strings.xml @@ -93,6 +93,8 @@ "Nakalipas na 1 oras" "Nakalipas na 15 minuto" "Walang paggamit ng pahintulot" + "Paggamit ng pahintulot sa app" + "%1$s na ang nakalipas" %s araw %s na araw diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml index bfdefa92a..b16861cda 100644 --- a/res/values-tr/strings.xml +++ b/res/values-tr/strings.xml @@ -93,6 +93,8 @@ "Son 1 saat" "Son 15 dakika" "İzin kullanılmadı" + "Uygulama izinleri kullanımı" + "%1$s önce" %s gün 1 gün diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml index a8a2701a0..c5286e6e6 100644 --- a/res/values-uk/strings.xml +++ b/res/values-uk/strings.xml @@ -95,6 +95,8 @@ "Остання година" "Останні 15 хвилин" "Дозволи не використовувалися" + "Використання дозволів додатка" + "%1$s тому" %s день %s дні diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml index 14a02d3d7..959899a3b 100644 --- a/res/values-ur/strings.xml +++ b/res/values-ur/strings.xml @@ -93,6 +93,8 @@ "آخری 1 گھنٹہ" "آخری 15 منٹ" "اجازت کا استعمال نہیں ہوا ہے" + "ایپ کی اجازتوں کا استعمال" + "%1$s پہلے" %s دن 1 دن diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml index 578cc3be6..e816d329c 100644 --- a/res/values-uz/strings.xml +++ b/res/values-uz/strings.xml @@ -93,6 +93,8 @@ "Oxirgi 1 soat" "Oxirgi 15 daqiqa" "Ruxsatlardan foydalanilmagan" + "Ilovalar uchun ruxsatlar" + "%1$s oldin" %s kun 1 kun diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml index 8687164ff..482f11b65 100644 --- a/res/values-vi/strings.xml +++ b/res/values-vi/strings.xml @@ -93,6 +93,8 @@ "1 giờ qua" "15 phút trước" "Không sử dụng quyền" + "Sử dụng quyền ứng dụng" + "%1$s trước" %s ngày 1 ngày diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml index 3cacd5aa8..8019cdf7d 100644 --- a/res/values-zh-rCN/strings.xml +++ b/res/values-zh-rCN/strings.xml @@ -93,6 +93,8 @@ "过去 1 小时" "过去 15 分钟" "没有使用此权限的应用" + "应用权限使用情况" + "%1$s前" %s 1 天 diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml index ae6e8cd5d..fff6d5538 100644 --- a/res/values-zh-rHK/strings.xml +++ b/res/values-zh-rHK/strings.xml @@ -93,6 +93,8 @@ "過去 1 小時" "過去 15 分鐘" "沒有應用程式使用要求的權限" + "應用程式權限使用情況" + "%1$s前" %s 1 天 diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml index ced75a24b..66bd0edb5 100644 --- a/res/values-zh-rTW/strings.xml +++ b/res/values-zh-rTW/strings.xml @@ -93,6 +93,8 @@ "過去 1 小時" "過去 15 分鐘" "沒有使用此權限的應用程式" + "應用程式權限使用情況" + "%1$s前" %s 1 天 diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml index 0a00806ad..057b3f804 100644 --- a/res/values-zu/strings.xml +++ b/res/values-zu/strings.xml @@ -93,6 +93,8 @@ "Ihora lokugcina elingu-1" "Amaminithi angu-15 okugcina" "Akukho ukusetshenziswa kwemvume" + "Ukusetshenziswa kwezimvume zohlelo lokusebenza" + "%1$s edlule" %s izinsuku %s izinsuku -- GitLab From 67874f3ae24f5754acdd72391922988c4456c8d1 Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Tue, 13 Nov 2018 14:42:56 -0800 Subject: [PATCH 131/701] Use Html.fromHtml() for role request message. This allows bolding the app names in the role request message. Bug: 110557011 Test: build Change-Id: Ie91491d352a4500c25a30c7f6d7e45f9f6b19e06 --- .../packageinstaller/role/ui/RequestRoleFragment.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java b/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java index a2bf2d497..97d463c75 100644 --- a/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java +++ b/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java @@ -23,6 +23,7 @@ import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.os.Bundle; +import android.text.Html; import android.util.Log; import androidx.annotation.NonNull; @@ -113,13 +114,14 @@ public class RequestRoleFragment extends DialogFragment { String currentApplicationLabel = role.isExclusive() ? getCurrentApplicationLabel( currentPackageNames, context) : null; - String message; + String messageHtml; if (currentApplicationLabel == null) { - message = getString(R.string.role_request_message_add, applicationLabel, roleLabel); + messageHtml = getString(R.string.role_request_message_add, applicationLabel, roleLabel); } else { - message = getString(R.string.role_request_message_replace, applicationLabel, + messageHtml = getString(R.string.role_request_message_replace, applicationLabel, currentApplicationLabel, roleLabel); } + CharSequence message = Html.fromHtml(messageHtml, Html.FROM_HTML_MODE_LEGACY); return new AlertDialog.Builder(context, getTheme()) .setMessage(message) -- GitLab From 6eb17d5262c5ca0f2b512011d49804d475c69826 Mon Sep 17 00:00:00 2001 From: Eugene Susla Date: Fri, 9 Nov 2018 10:37:17 -0800 Subject: [PATCH 132/701] Groundwork for default grants in RoleController This lays out some plumbing for moving the DfaultPermissionGrantPolicy grants over to RoleControllerService Test: enable DEBUG flag and `adb logcat | grep -n5 Role` Change-Id: Ic8e0253a51d6afe1e34ea7cf4e1f26c7e5f7b84e --- .../role/service/RoleControllerServiceImpl.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/com/android/packageinstaller/role/service/RoleControllerServiceImpl.java b/src/com/android/packageinstaller/role/service/RoleControllerServiceImpl.java index 0226676f0..8f879e0d4 100644 --- a/src/com/android/packageinstaller/role/service/RoleControllerServiceImpl.java +++ b/src/com/android/packageinstaller/role/service/RoleControllerServiceImpl.java @@ -21,6 +21,7 @@ import android.app.role.RoleManagerCallback; import android.content.pm.ApplicationInfo; import android.os.Handler; import android.os.HandlerThread; +import android.os.UserHandle; import android.rolecontrollerservice.RoleControllerService; import android.text.TextUtils; import android.util.Log; @@ -119,6 +120,13 @@ public class RoleControllerServiceImpl extends RoleControllerService { mWorkerHandler.post(() -> clearRoleHolders(roleName, callback)); } + @Override + public void onGrantDefaultRoles(@NonNull RoleManagerCallback callback) { + //TODO grant default permissions and appops + Log.i(LOG_TAG, "Granting defaults for user " + UserHandle.myUserId()); + callback.onSuccess(); + } + @WorkerThread private void addRoleHolder(@NonNull String roleName, @NonNull String packageName, @NonNull RoleManagerCallback callback) { -- GitLab From ef8c82470e313d9f36dd8035a91983220c33b7d9 Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Wed, 14 Nov 2018 09:14:43 -0800 Subject: [PATCH 133/701] Add more owners to permssion controller Test: none Change-Id: I2abb5dbf499a620f2a73a6adc27e631205afd7df --- OWNERS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OWNERS b/OWNERS index 3bdeab6c0..bda45f606 100644 --- a/OWNERS +++ b/OWNERS @@ -1,6 +1,9 @@ svetoslavganov@google.com moltmann@google.com toddke@google.com +zhanghai@google.com +evanseverson@google.com +eugenesusla@google.com # For automotive related changes stenning@google.com -- GitLab From 89bdb3984364f0e0884e8ba94ab347fd6b471ae1 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Wed, 7 Nov 2018 16:14:52 -0800 Subject: [PATCH 134/701] Add the new app permission screen. This screen allows toggling the permission (either dual- or tri-state) and will eventually show the permission justification. It will also replace PermissionPreference, from which most of the logic is copied. This modifies PermissionUsagePreference so that clicks go to this page instead of the old PermissionPreference pages. Bug: 63532550 Bug: 118437704 Test: Used the new screen to toggle permissions. Test: Manually forced the code down the paths of the rare conditions. Change-Id: I7afa8d2ca88d495e824000dd4cbcb66d887aef91 --- res/drawable/ic_info.xml | 25 + res/drawable/ic_settings.xml | 34 + res/drawable/list_divider_dark.xml | 24 + res/layout/app_permission.xml | 145 ++++ res/values/strings.xml | 24 + .../permission/model/AppPermissionUsage.java | 20 + .../ui/ManagePermissionsActivity.java | 17 + .../ui/handheld/AppPermissionFragment.java | 666 ++++++++++++++++++ .../handheld/AppPermissionUsageFragment.java | 2 +- .../handheld/PermissionUsagePreference.java | 3 +- 10 files changed, 958 insertions(+), 2 deletions(-) create mode 100644 res/drawable/ic_info.xml create mode 100644 res/drawable/ic_settings.xml create mode 100644 res/drawable/list_divider_dark.xml create mode 100644 res/layout/app_permission.xml create mode 100644 src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java diff --git a/res/drawable/ic_info.xml b/res/drawable/ic_info.xml new file mode 100644 index 000000000..365bd338a --- /dev/null +++ b/res/drawable/ic_info.xml @@ -0,0 +1,25 @@ + + + + \ No newline at end of file diff --git a/res/drawable/ic_settings.xml b/res/drawable/ic_settings.xml new file mode 100644 index 000000000..28fb10dfa --- /dev/null +++ b/res/drawable/ic_settings.xml @@ -0,0 +1,34 @@ + + + + \ No newline at end of file diff --git a/res/drawable/list_divider_dark.xml b/res/drawable/list_divider_dark.xml new file mode 100644 index 000000000..c5af982bd --- /dev/null +++ b/res/drawable/list_divider_dark.xml @@ -0,0 +1,24 @@ + + + + + + + \ No newline at end of file diff --git a/res/layout/app_permission.xml b/res/layout/app_permission.xml new file mode 100644 index 000000000..bfe0f7816 --- /dev/null +++ b/res/layout/app_permission.xml @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/values/strings.xml b/res/values/strings.xml index 611ccd67a..cf7dd5fb0 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -270,6 +270,30 @@ %1$s ago + + Allow + + + Allow all the time + + + Allow only while the app is in use + + + Deny + + + %1$s permission + + + %1$s access for %2$s + + + %1$s accessed your %2$s %3$s ago. + + + View detailed permissions usage + 1 day diff --git a/src/com/android/packageinstaller/permission/model/AppPermissionUsage.java b/src/com/android/packageinstaller/permission/model/AppPermissionUsage.java index 95c906698..66d032c91 100644 --- a/src/com/android/packageinstaller/permission/model/AppPermissionUsage.java +++ b/src/com/android/packageinstaller/permission/model/AppPermissionUsage.java @@ -20,6 +20,9 @@ import android.app.AppOpsManager; import androidx.annotation.NonNull; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + /** * A single instance of an app accessing a permission. */ @@ -56,4 +59,21 @@ public final class AppPermissionUsage { public @NonNull CharSequence getPermissionGroupLabel() { return mPermissionGroupLabel; } + + /** + * Get the name of the permission (not the group) this represents. + * + * @return the name of the permission this represents. + */ + public String getPermissionName() { + // TODO: Replace reflection with a proper API (probably in AppOpsManager). + try { + Method getOpMethod = AppOpsManager.OpEntry.class.getMethod("getOp"); + Method opToPermissionMethod = AppOpsManager.class.getMethod("opToPermission", + int.class); + return (String) opToPermissionMethod.invoke(null, (int) getOpMethod.invoke(mOp)); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + return null; + } + } } diff --git a/src/com/android/packageinstaller/permission/ui/ManagePermissionsActivity.java b/src/com/android/packageinstaller/permission/ui/ManagePermissionsActivity.java index 20b668e29..0dc680ecf 100644 --- a/src/com/android/packageinstaller/permission/ui/ManagePermissionsActivity.java +++ b/src/com/android/packageinstaller/permission/ui/ManagePermissionsActivity.java @@ -131,6 +131,23 @@ public final class ManagePermissionsActivity extends FragmentActivity { .AppPermissionUsageFragment.newInstance(packageName); } break; + case Intent.ACTION_MANAGE_APP_PERMISSION: { + String packageName = getIntent().getStringExtra(Intent.EXTRA_PACKAGE_NAME); + if (packageName == null) { + Log.i(LOG_TAG, "Missing mandatory argument EXTRA_PACKAGE_NAME"); + finish(); + return; + } + permissionName = getIntent().getStringExtra(Intent.EXTRA_PERMISSION_NAME); + if (permissionName == null) { + Log.i(LOG_TAG, "Missing mandatory argument EXTRA_PERMISSION_NAME"); + finish(); + return; + } + androidXFragment = com.android.packageinstaller.permission.ui.handheld + .AppPermissionFragment.newInstance(packageName, permissionName); + } break; + default: { Log.w(LOG_TAG, "Unrecognized action " + action); finish(); diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java new file mode 100644 index 000000000..a903f3bed --- /dev/null +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java @@ -0,0 +1,666 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.packageinstaller.permission.ui.handheld; + +import static java.lang.annotation.RetentionPolicy.SOURCE; + +import android.app.ActionBar; +import android.app.Activity; +import android.app.AlertDialog; +import android.app.Dialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.os.UserHandle; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.RadioButton; +import android.widget.RadioGroup; +import android.widget.TextView; + +import androidx.annotation.IntDef; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.DialogFragment; +import androidx.fragment.app.Fragment; + +import com.android.packageinstaller.permission.model.AppPermissionGroup; +import com.android.packageinstaller.permission.model.AppPermissionUsage; +import com.android.packageinstaller.permission.utils.IconDrawableFactory; +import com.android.packageinstaller.permission.utils.LocationUtils; +import com.android.packageinstaller.permission.utils.Utils; +import com.android.permissioncontroller.R; +import com.android.settingslib.RestrictedLockUtils; +import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; + +import java.lang.annotation.Retention; +import java.util.List; + +/** + * Show and manage a single permission group for an app. + * + *

Allows the user to control whether the app is granted the permission. + */ +public class AppPermissionFragment extends PermissionsFrameFragment { + private static final String LOG_TAG = "AppPermissionFragment"; + + @Retention(SOURCE) + @IntDef(value = {CHANGE_FOREGROUND, CHANGE_BACKGROUND}, flag = true) + @interface ChangeTarget {} + static final int CHANGE_FOREGROUND = 1; + static final int CHANGE_BACKGROUND = 2; + static final int CHANGE_BOTH = CHANGE_FOREGROUND | CHANGE_BACKGROUND; + + private @NonNull AppPermissionGroup mGroup; + + private @NonNull RadioGroup mRadioGroup; + private @NonNull RadioButton mAlwaysButton; + private @NonNull RadioButton mForegroundOnlyButton; + private @NonNull RadioButton mDenyButton; + private @NonNull View mDivider; + private @NonNull ViewGroup mWidgetFrame; + private @NonNull TextView mPermissionDetails; + + private boolean mHasConfirmedRevoke; + + /** + * @return A new fragment + */ + public static @NonNull AppPermissionFragment newInstance(@NonNull String packageName, + @NonNull String permissionName) { + AppPermissionFragment fragment = new AppPermissionFragment(); + Bundle arguments = new Bundle(); + arguments.putString(Intent.EXTRA_PACKAGE_NAME, packageName); + arguments.putString(Intent.EXTRA_PERMISSION_NAME, permissionName); + fragment.setArguments(arguments); + return fragment; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setHasOptionsMenu(true); + ActionBar ab = getActivity().getActionBar(); + if (ab != null) { + ab.setDisplayHomeAsUpEnabled(true); + } + + String packageName = getArguments().getString(Intent.EXTRA_PACKAGE_NAME); + Activity activity = getActivity(); + Context context = getPreferenceManager().getContext(); + mGroup = AppPermissionGroup.create(context, getPackageInfo(activity, packageName), + getArguments().getString(Intent.EXTRA_PERMISSION_NAME), false); + + if (mGroup == null || !Utils.shouldShowPermission(context, mGroup)) { + Log.i(LOG_TAG, "Illegal group: " + (mGroup == null ? "null" : mGroup.getName())); + activity.setResult(Activity.RESULT_CANCELED); + activity.finish(); + return; + } + + mHasConfirmedRevoke = false; + + activity.setTitle(context.getString(R.string.app_permission_title, mGroup.getLabel())); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + Context context = getPreferenceManager().getContext(); + ViewGroup root = (ViewGroup) inflater.inflate(R.layout.app_permission, container, false); + + if (mGroup == null) { + return root; + } + + String appLabel = Utils.getAppLabel(mGroup.getApp().applicationInfo, context); + + ((ImageView) root.requireViewById(R.id.icon)).setImageDrawable(getAppIcon()); + ((TextView) root.requireViewById(R.id.name)).setText(appLabel); + root.requireViewById(R.id.info).setVisibility(View.GONE); + + ((TextView) root.requireViewById(R.id.permission_message)).setText( + context.getString(R.string.app_permission_header, mGroup.getLabel(), appLabel)); + + ((TextView) root.requireViewById(R.id.usage_summary)).setText( + context.getString( + R.string.app_permission_footer_usage_summary, + appLabel, + mGroup.getLabel().toString().toLowerCase(), getUsageTimeDiffString())); + + TextView usageLink = root.requireViewById(R.id.usage_link); + usageLink.setText(context.getString(R.string.app_permission_footer_usage_link)); + usageLink.setOnClickListener((v) -> { + Intent intent = new Intent(Intent.ACTION_REVIEW_APP_PERMISSION_USAGE); + intent.putExtra(Intent.EXTRA_PACKAGE_NAME, mGroup.getApp().packageName); + context.startActivity(intent); + }); + + mRadioGroup = root.requireViewById(R.id.radiogroup); + mAlwaysButton = root.requireViewById(R.id.allow_radio_button); + mForegroundOnlyButton = root.requireViewById(R.id.foreground_only_radio_button); + mDenyButton = root.requireViewById(R.id.deny_radio_button); + mDivider = root.requireViewById(R.id.two_target_divider); + mWidgetFrame = root.requireViewById(R.id.widget_frame); + mPermissionDetails = root.requireViewById(R.id.permission_details); + + updateButtons(); + + return root; + } + + /** + * Build a string representing the amount of time passed since the most recent permission usage + * by this AppPermissionGroup. + * + * @return a string representing the amount of time since this app's most recent permission + * usage. + */ + private @NonNull String getUsageTimeDiffString() { + long mostRecentTime = 0; + List groupUsages = mGroup.getAppPermissionUsage(); + int numUsages = groupUsages.size(); + for (int usageNum = 0; usageNum < numUsages; usageNum++) { + AppPermissionUsage usage = groupUsages.get(usageNum); + mostRecentTime = Math.max(mostRecentTime, usage.getTime()); + } + if (mostRecentTime == 0) { + Log.e(LOG_TAG, "Unexpected usage time of 0."); + } + return Utils.getTimeDiffStr(getContext(), System.currentTimeMillis() - mostRecentTime); + } + + private void updateButtons() { + // Reset everything to the "default" state: tri-state buttons are shown with exactly one + // selected and no special messages. + mDivider.setVisibility(View.GONE); + mWidgetFrame.setVisibility(View.GONE); + mPermissionDetails.setVisibility(View.GONE); + + if (mGroup.areRuntimePermissionsGranted()) { + if (!mGroup.hasPermissionWithBackgroundMode() + || (mGroup.getBackgroundPermissions() != null + && mGroup.getBackgroundPermissions().areRuntimePermissionsGranted())) { + setCheckedButton(mAlwaysButton); + } else { + setCheckedButton(mForegroundOnlyButton); + } + } else { + setCheckedButton(mDenyButton); + } + + mAlwaysButton.setOnClickListener((v) -> requestChange(true, CHANGE_BOTH)); + mForegroundOnlyButton.setOnClickListener((v) -> { + requestChange(false, CHANGE_BACKGROUND); + requestChange(true, CHANGE_FOREGROUND); + }); + mDenyButton.setOnClickListener((v) -> requestChange(false, CHANGE_BOTH)); + + // Handle the UI for various special cases. + Context context = getContext(); + if (isPolicyFullyFixed() || isForegroundDisabledByPolicy()) { + // Disable changing permissions and potentially show administrator message. + EnforcedAdmin admin = getAdmin(); + if (admin != null) { + mAlwaysButton.setEnabled(false); + mForegroundOnlyButton.setEnabled(false); + mDenyButton.setEnabled(false); + + showRightIcon(R.drawable.ic_info); + mWidgetFrame.setOnClickListener(v -> + RestrictedLockUtils.sendShowAdminSupportDetailsIntent(context, admin) + ); + } else { + mAlwaysButton.setEnabled(false); + mForegroundOnlyButton.setEnabled(false); + mDenyButton.setEnabled(false); + } + updateDetailForFixedByPolicyPermissionGroup(); + } else if (Utils.areGroupPermissionsIndividuallyControlled(context, mGroup.getName())) { + // If the permissions are individually controlled, also show a link to the page that + // lets you control them. + mDivider.setVisibility(View.VISIBLE); + showRightIcon(R.drawable.ic_settings); + mWidgetFrame.setOnClickListener(v -> showAllPermissions(mGroup.getName())); + } else { + if (mGroup.hasPermissionWithBackgroundMode()) { + if (mGroup.getBackgroundPermissions() == null) { + // The group has background permissions but the app did not request any. I.e. + // The app can only switch between 'never" and "only in foreground". + mAlwaysButton.setEnabled(false); + + mDenyButton.setOnClickListener((v) -> requestChange(false, CHANGE_FOREGROUND)); + } else { + if (isBackgroundPolicyFixed()) { + // If background policy is fixed, we only allow switching the foreground. + // Note that this assumes that the background policy is fixed to deny, + // since if it is fixed to grant, so is the foreground. + mAlwaysButton.setEnabled(false); + setCheckedButton(mForegroundOnlyButton); + + mDenyButton.setOnClickListener( + (v) -> requestChange(false, CHANGE_FOREGROUND)); + + updateDetailForFixedByPolicyPermissionGroup(); + } else if (isForegroundPolicyFixed()) { + // Foreground permissions are fixed to allow (the first case above handles + // fixing to deny), so we only allow toggling background permissions. + mDenyButton.setEnabled(false); + + mAlwaysButton.setOnClickListener( + (v) -> requestChange(true, CHANGE_BACKGROUND)); + mForegroundOnlyButton.setOnClickListener( + (v) -> requestChange(false, CHANGE_BACKGROUND)); + + updateDetailForFixedByPolicyPermissionGroup(); + } else { + // The default tri-state case is handled by default. + } + } + + } else { + // The default bi-state. + mForegroundOnlyButton.setVisibility(View.GONE); + mAlwaysButton.setText(context.getString(R.string.app_permission_button_allow)); + } + } + } + + /** + * Set the given button as the only checked button in the radio group. + * + * @param button the button that should be checked. + */ + private void setCheckedButton(@NonNull RadioButton button) { + mRadioGroup.clearCheck(); + button.setChecked(true); + if (button != mAlwaysButton) { + mAlwaysButton.setChecked(false); + } + if (button != mForegroundOnlyButton) { + mForegroundOnlyButton.setChecked(false); + } + if (button != mDenyButton) { + mDenyButton.setChecked(false); + } + } + + /** + * Show the given icon on the right of the first radio button. + * + * @param iconId the resourceId of the drawable to use. + */ + private void showRightIcon(int iconId) { + mWidgetFrame.removeAllViews(); + ImageView imageView = new ImageView(getPreferenceManager().getContext()); + imageView.setImageResource(iconId); + mWidgetFrame.addView(imageView); + mWidgetFrame.setVisibility(View.VISIBLE); + } + + private static @Nullable PackageInfo getPackageInfo(@NonNull Activity activity, + @NonNull String packageName) { + try { + return activity.getPackageManager().getPackageInfo( + packageName, PackageManager.GET_PERMISSIONS); + } catch (PackageManager.NameNotFoundException e) { + Log.i(LOG_TAG, "No package: " + activity.getCallingPackage(), e); + activity.setResult(Activity.RESULT_CANCELED); + activity.finish(); + return null; + } + } + + /** + * Is any foreground permissions of this group fixed by the policy, i.e. not changeable by the + * user. + * + * @return {@code true} iff any foreground permission is fixed + */ + private boolean isForegroundPolicyFixed() { + return mGroup.isPolicyFixed(); + } + + /** + * Is any background permissions of this group fixed by the policy, i.e. not changeable by the + * user. + * + * @return {@code true} iff any background permission is fixed + */ + private boolean isBackgroundPolicyFixed() { + return mGroup.getBackgroundPermissions() != null + && mGroup.getBackgroundPermissions().isPolicyFixed(); + } + + /** + * Are there permissions fixed, so that the user cannot change the preference at all? + * + * @return {@code true} iff the permissions of this group are fixed + */ + private boolean isPolicyFullyFixed() { + return isForegroundPolicyFixed() && (mGroup.getBackgroundPermissions() == null + || isBackgroundPolicyFixed()); + } + + /** + * Is the foreground part of this group disabled. If the foreground is disabled, there is no + * need to possible grant background access. + * + * @return {@code true} iff the permissions of this group are fixed + */ + private boolean isForegroundDisabledByPolicy() { + return isForegroundPolicyFixed() && !mGroup.areRuntimePermissionsGranted(); + } + + /** + * Get the app that acts as admin for this profile. + * + * @return The admin or {@code null} if there is no admin. + */ + private @Nullable EnforcedAdmin getAdmin() { + return RestrictedLockUtils.getProfileOrDeviceOwner(getContext(), mGroup.getUser()); + } + + /** + * Update the detail of a permission group that is at least partially fixed by policy. + */ + private void updateDetailForFixedByPolicyPermissionGroup() { + EnforcedAdmin admin = getAdmin(); + AppPermissionGroup backgroundGroup = mGroup.getBackgroundPermissions(); + + boolean hasAdmin = admin != null; + + if (isForegroundDisabledByPolicy()) { + // Permission is fully controlled by policy and cannot be switched + + if (hasAdmin) { + setDetail(R.string.disabled_by_admin); + } else { + // Disabled state will be displayed by switch, so no need to add text for that + setDetail(R.string.permission_summary_enforced_by_policy); + } + } else if (isPolicyFullyFixed()) { + // Permission is fully controlled by policy and cannot be switched + + if (backgroundGroup == null) { + if (hasAdmin) { + setDetail(R.string.enabled_by_admin); + } else { + // Enabled state will be displayed by switch, so no need to add text for + // that + setDetail(R.string.permission_summary_enforced_by_policy); + } + } else { + if (backgroundGroup.areRuntimePermissionsGranted()) { + if (hasAdmin) { + setDetail(R.string.enabled_by_admin); + } else { + // Enabled state will be displayed by switch, so no need to add text for + // that + setDetail(R.string.permission_summary_enforced_by_policy); + } + } else { + if (hasAdmin) { + setDetail( + R.string.permission_summary_enabled_by_admin_foreground_only); + } else { + setDetail( + R.string.permission_summary_enabled_by_policy_foreground_only); + } + } + } + } else { + // Part of the permission group can still be switched + + if (isBackgroundPolicyFixed()) { + if (backgroundGroup.areRuntimePermissionsGranted()) { + if (hasAdmin) { + setDetail(R.string.permission_summary_enabled_by_admin_background_only); + } else { + setDetail(R.string.permission_summary_enabled_by_policy_background_only); + } + } else { + if (hasAdmin) { + setDetail(R.string.permission_summary_disabled_by_admin_background_only); + } else { + setDetail(R.string.permission_summary_disabled_by_policy_background_only); + } + } + } else if (isForegroundPolicyFixed()) { + if (hasAdmin) { + setDetail(R.string.permission_summary_enabled_by_admin_foreground_only); + } else { + setDetail(R.string.permission_summary_enabled_by_policy_foreground_only); + } + } + } + } + + /** + * Show the given string as informative text below the radio buttons. + * @param strId the resourceId of the string to display. + */ + private void setDetail(int strId) { + mPermissionDetails.setText(getPreferenceManager().getContext().getString(strId)); + mPermissionDetails.setVisibility(View.VISIBLE); + } + + /** + * Show all individual permissions in this group in a new fragment. + */ + private void showAllPermissions(@NonNull String filterGroup) { + Fragment frag = AllAppPermissionsFragment.newInstance(mGroup.getApp().packageName, + filterGroup); + getFragmentManager().beginTransaction() + .replace(android.R.id.content, frag) + .addToBackStack("AllPerms") + .commit(); + } + + /** + * Get the icon of this app. + * + * @return the app's icon. + */ + private @NonNull Drawable getAppIcon() { + ApplicationInfo appInfo = mGroup.getApp().applicationInfo; + return IconDrawableFactory.getBadgedIcon(getActivity(), appInfo, + UserHandle.getUserHandleForUid(appInfo.uid)); + } + + /** + * Request to grant/revoke permissions group. + * + *

Does not handle: + *

    + *
  • Individually granted permissions
  • + *
  • Permission groups with background permissions
  • + *
+ *

Does handle: + *

    + *
  • Default grant permissions
  • + *
+ * + * @param requestGrant If this group should be granted + * @param changeTarget Which permission group (foreground/background/both) should be changed + * + * @return If the request was processed. + */ + private boolean requestChange(boolean requestGrant, @ChangeTarget int changeTarget) { + if (LocationUtils.isLocationGroupAndProvider(getContext(), mGroup.getName(), + mGroup.getApp().packageName)) { + LocationUtils.showLocationDialog(getContext(), + Utils.getAppLabel(mGroup.getApp().applicationInfo, getContext())); + + // The request was denied, so update the buttons. + updateButtons(); + return false; + } + + if (requestGrant) { + if ((changeTarget & CHANGE_FOREGROUND) != 0) { + mGroup.grantRuntimePermissions(false); + } + if ((changeTarget & CHANGE_BACKGROUND) != 0) { + if (mGroup.getBackgroundPermissions() != null) { + mGroup.getBackgroundPermissions().grantRuntimePermissions(false); + } + } + } else { + boolean requestToRevokeGrantedByDefault = false; + + if ((changeTarget & CHANGE_FOREGROUND) != 0 + && mGroup.areRuntimePermissionsGranted()) { + requestToRevokeGrantedByDefault = mGroup.hasGrantedByDefaultPermission(); + } + if ((changeTarget & CHANGE_BACKGROUND) != 0) { + if (mGroup.getBackgroundPermissions() != null + && mGroup.getBackgroundPermissions().areRuntimePermissionsGranted()) { + requestToRevokeGrantedByDefault |= + mGroup.getBackgroundPermissions().hasGrantedByDefaultPermission(); + } + } + + if ((requestToRevokeGrantedByDefault || !mGroup.doesSupportRuntimePermissions()) + && !mHasConfirmedRevoke) { + showDefaultDenyDialog(changeTarget); + updateButtons(); + return false; + } else { + if ((changeTarget & CHANGE_FOREGROUND) != 0 + && mGroup.areRuntimePermissionsGranted()) { + mGroup.revokeRuntimePermissions(false); + } + if ((changeTarget & CHANGE_BACKGROUND) != 0) { + if (mGroup.getBackgroundPermissions() != null + && mGroup.getBackgroundPermissions().areRuntimePermissionsGranted()) { + mGroup.getBackgroundPermissions().revokeRuntimePermissions(false); + } + } + } + } + + updateButtons(); + + return true; + } + + /** + * Show a dialog that warns the user that she/he is about to revoke permissions that were + * granted by default. + * + *

The order of operation to revoke a permission granted by default is: + *

    + *
  1. {@code showDefaultDenyDialog}
  2. + *
  3. {@link DefaultDenyDialog#onCreateDialog}
  4. + *
  5. {@link AppPermissionFragment#onDenyAnyWay}
  6. + *
+ * + * @param changeTarget Whether background or foreground should be changed + */ + private void showDefaultDenyDialog(@ChangeTarget int changeTarget) { + Bundle args = new Bundle(); + + boolean showGrantedByDefaultWarning = false; + if ((changeTarget & CHANGE_FOREGROUND) != 0) { + showGrantedByDefaultWarning = mGroup.hasGrantedByDefaultPermission(); + } + if ((changeTarget & CHANGE_BACKGROUND) != 0) { + if (mGroup.getBackgroundPermissions() != null) { + showGrantedByDefaultWarning |= + mGroup.getBackgroundPermissions().hasGrantedByDefaultPermission(); + } + } + + args.putInt(DefaultDenyDialog.MSG, showGrantedByDefaultWarning ? R.string.system_warning + : R.string.old_sdk_deny_warning); + args.putInt(DefaultDenyDialog.CHANGE_TARGET, changeTarget); + + DefaultDenyDialog defaultDenyDialog = new DefaultDenyDialog(this); + defaultDenyDialog.setArguments(args); + defaultDenyDialog.show(getFragmentManager().beginTransaction(), + "denyDefault"); + } + + /** + * Once we user has confirmed that he/she wants to revoke a permission that was granted by + * default, actually revoke the permissions. + * + * @param changeTarget whether to change foreground, background, or both. + * + * @see #showDefaultDenyDialog(int) + */ + void onDenyAnyWay(@ChangeTarget int changeTarget) { + boolean hasDefaultPermissions = false; + if ((changeTarget & CHANGE_FOREGROUND) != 0) { + mGroup.revokeRuntimePermissions(false); + hasDefaultPermissions = mGroup.hasGrantedByDefaultPermission(); + } + if ((changeTarget & CHANGE_BACKGROUND) != 0) { + if (mGroup.getBackgroundPermissions() != null) { + mGroup.getBackgroundPermissions().revokeRuntimePermissions(false); + hasDefaultPermissions |= + mGroup.getBackgroundPermissions().hasGrantedByDefaultPermission(); + } + } + + if (hasDefaultPermissions || !mGroup.doesSupportRuntimePermissions()) { + mHasConfirmedRevoke = true; + } + updateButtons(); + } + + /** + * A dialog warning the user that she/he is about to deny a permission that was granted by + * default. + * + * @see #showDefaultDenyDialog(int) + */ + public static class DefaultDenyDialog extends DialogFragment { + private static final String MSG = DefaultDenyDialog.class.getName() + ".arg.msg"; + private static final String CHANGE_TARGET = DefaultDenyDialog.class.getName() + + ".arg.changeTarget"; + private static final String KEY = DefaultDenyDialog.class.getName() + ".arg.key"; + + private @NonNull AppPermissionFragment mFragment; + + public DefaultDenyDialog(@NonNull AppPermissionFragment fragment) { + mFragment = fragment; + } + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + AlertDialog.Builder b = new AlertDialog.Builder(getContext()) + .setMessage(getArguments().getInt(MSG)) + .setNegativeButton(R.string.cancel, + (DialogInterface dialog, int which) -> mFragment.updateButtons()) + .setPositiveButton(R.string.grant_dialog_button_deny_anyway, + (DialogInterface dialog, int which) -> + mFragment.onDenyAnyWay(getArguments().getInt(CHANGE_TARGET))); + + return b.create(); + } + } +} diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java index a9d2b88bb..5f1e7c40c 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java @@ -156,7 +156,7 @@ public class AppPermissionUsageFragment extends SettingsWithHeader { if (group.getLabel().equals("Storage")) { continue; } - if (!Utils.shouldShowPermission(getContext(), group)) { + if (!Utils.shouldShowPermission(context, group)) { continue; } List groupUsages = group.getAppPermissionUsage(); diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsagePreference.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsagePreference.java index e2fe91210..fbfb42d27 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsagePreference.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsagePreference.java @@ -49,8 +49,9 @@ public class PermissionUsagePreference extends Preference { setTitle(title); setSummary(summary); setOnPreferenceClickListener(preference -> { - Intent intent = new Intent(Intent.ACTION_MANAGE_APP_PERMISSIONS); + Intent intent = new Intent(Intent.ACTION_MANAGE_APP_PERMISSION); intent.putExtra(Intent.EXTRA_PACKAGE_NAME, usage.getPackageName()); + intent.putExtra(Intent.EXTRA_PERMISSION_NAME, usage.getPermissionName()); context.startActivity(intent); return true; }); -- GitLab From 291adff74ae76e274e8ccb9e5b9e88ddacb00c8a Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Tue, 13 Nov 2018 15:26:37 -0800 Subject: [PATCH 135/701] Add label attribute for roles. This change adds a required label resource attribute for roles, so that we can show role names to users. Bug: 110557011 Test: build Change-Id: I4f28c226927f070f0e58de9773b42ca698ee69b8 --- res/values/strings.xml | 11 ++ res/xml/roles.xml | 6 +- .../packageinstaller/role/model/Role.java | 15 +- .../packageinstaller/role/model/Roles.java | 158 +++++++++++------- .../role/ui/RequestRoleFragment.java | 3 +- 5 files changed, 122 insertions(+), 71 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 611ccd67a..d6f3bed06 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -304,4 +304,15 @@ <b>%1$s</b> instead of <b>%1$s</b> as your %2$s?
+ + + + + Phone app + + + SMS app + + + Browser app diff --git a/res/xml/roles.xml b/res/xml/roles.xml index 3df3da1fc..1530494e9 100644 --- a/res/xml/roles.xml +++ b/res/xml/roles.xml @@ -95,7 +95,7 @@ - + @@ -134,7 +134,7 @@ - + @@ -215,7 +215,7 @@ - + diff --git a/src/com/android/packageinstaller/role/model/Role.java b/src/com/android/packageinstaller/role/model/Role.java index adbe49a5e..7f48e2b9e 100644 --- a/src/com/android/packageinstaller/role/model/Role.java +++ b/src/com/android/packageinstaller/role/model/Role.java @@ -24,6 +24,7 @@ import android.util.ArrayMap; import android.util.Log; import androidx.annotation.NonNull; +import androidx.annotation.StringRes; import com.android.packageinstaller.role.utils.PackageUtils; @@ -57,6 +58,12 @@ public class Role { @NonNull private final String mName; + /** + * The string resource for the label of this role. + */ + @StringRes + private final int mLabelResource; + /** * Whether this role is exclusive, i.e. allows at most one holder. */ @@ -86,10 +93,11 @@ public class Role { @NonNull private final List mPreferredActivities; - public Role(@NonNull String name, boolean exclusive, + public Role(@NonNull String name, @StringRes int labelResource, boolean exclusive, @NonNull List requiredComponents, @NonNull List permissions, @NonNull List appOps, @NonNull List preferredActivities) { mName = name; + mLabelResource = labelResource; mExclusive = exclusive; mRequiredComponents = requiredComponents; mPermissions = permissions; @@ -102,6 +110,11 @@ public class Role { return mName; } + @StringRes + public int getLabelResource() { + return mLabelResource; + } + public boolean isExclusive() { return mExclusive; } diff --git a/src/com/android/packageinstaller/role/model/Roles.java b/src/com/android/packageinstaller/role/model/Roles.java index 27f773d74..9e0c84231 100644 --- a/src/com/android/packageinstaller/role/model/Roles.java +++ b/src/com/android/packageinstaller/role/model/Roles.java @@ -30,7 +30,6 @@ import androidx.annotation.Nullable; import com.android.permissioncontroller.R; -import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; @@ -71,6 +70,7 @@ public class Roles { private static final String TAG_PREFERRED_ACTIVITY = "preferred-activity"; private static final String ATTRIBUTE_NAME = "name"; private static final String ATTRIBUTE_EXCLUSIVE = "exclusive"; + private static final String ATTRIBUTE_LABEL = "label"; private static final String ATTRIBUTE_PERMISSION = "permission"; private static final String ATTRIBUTE_SCHEME = "scheme"; private static final String ATTRIBUTE_MIME_TYPE = "mimeType"; @@ -134,14 +134,14 @@ public class Roles { @Nullable private static Pair, Map> parseXml( - @NonNull XmlPullParser parser) throws IOException, XmlPullParserException { + @NonNull XmlResourceParser parser) throws IOException, XmlPullParserException { Pair, Map> xml = null; int outerDepth = parser.getDepth(); int type; - while ((type = parser.next()) != XmlPullParser.END_DOCUMENT - && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { - if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { + while ((type = parser.next()) != XmlResourceParser.END_DOCUMENT + && (type != XmlResourceParser.END_TAG || parser.getDepth() > outerDepth)) { + if (type == XmlResourceParser.END_TAG || type == XmlResourceParser.TEXT) { continue; } @@ -166,15 +166,15 @@ public class Roles { @NonNull private static Pair, Map> parseRoles( - @NonNull XmlPullParser parser) throws IOException, XmlPullParserException { + @NonNull XmlResourceParser parser) throws IOException, XmlPullParserException { Map permissionSets = new ArrayMap<>(); Map roles = new ArrayMap<>(); int outerDepth = parser.getDepth(); int type; - while ((type = parser.next()) != XmlPullParser.END_DOCUMENT - && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { - if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { + while ((type = parser.next()) != XmlResourceParser.END_DOCUMENT + && (type != XmlResourceParser.END_TAG || parser.getDepth() > outerDepth)) { + if (type == XmlResourceParser.END_TAG || type == XmlResourceParser.TEXT) { continue; } @@ -208,7 +208,7 @@ public class Roles { } @Nullable - private static PermissionSet parsePermissionSet(@NonNull XmlPullParser parser) + private static PermissionSet parsePermissionSet(@NonNull XmlResourceParser parser) throws IOException, XmlPullParserException { String name = requireAttributeValue(parser, ATTRIBUTE_NAME, TAG_PERMISSION_SET); if (name == null) { @@ -220,9 +220,9 @@ public class Roles { int outerDepth = parser.getDepth(); int type; - while ((type = parser.next()) != XmlPullParser.END_DOCUMENT - && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { - if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { + while ((type = parser.next()) != XmlResourceParser.END_DOCUMENT + && (type != XmlResourceParser.END_TAG || parser.getDepth() > outerDepth)) { + if (type == XmlResourceParser.END_TAG || type == XmlResourceParser.TEXT) { continue; } @@ -243,7 +243,7 @@ public class Roles { } @Nullable - private static Role parseRole(@NonNull XmlPullParser parser, + private static Role parseRole(@NonNull XmlResourceParser parser, @NonNull Map permissionSets) throws IOException, XmlPullParserException { String name = requireAttributeValue(parser, ATTRIBUTE_NAME, TAG_ROLE); @@ -252,18 +252,15 @@ public class Roles { return null; } - String exclusiveString = requireAttributeValue(parser, ATTRIBUTE_EXCLUSIVE, TAG_ROLE); - if (exclusiveString == null) { + Integer labelResource = requireAttributeResourceValue(parser, ATTRIBUTE_LABEL, 0, TAG_ROLE); + if (labelResource == null) { skipCurrentTag(parser); return null; } - boolean exclusive; - if (Objects.equals(exclusiveString, Boolean.toString(true))) { - exclusive = true; - } else if (Objects.equals(exclusiveString, Boolean.toString(false))) { - exclusive = false; - } else { - throwOrLogMessage("Unknown value for \"exclusive\" on : " + exclusiveString); + + Boolean exclusive = requireAttributeBooleanValue(parser, ATTRIBUTE_EXCLUSIVE, true, + TAG_ROLE); + if (exclusive == null) { skipCurrentTag(parser); return null; } @@ -275,9 +272,9 @@ public class Roles { int outerDepth = parser.getDepth(); int type; - while ((type = parser.next()) != XmlPullParser.END_DOCUMENT - && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { - if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { + while ((type = parser.next()) != XmlResourceParser.END_DOCUMENT + && (type != XmlResourceParser.END_TAG || parser.getDepth() > outerDepth)) { + if (type == XmlResourceParser.END_TAG || type == XmlResourceParser.TEXT) { continue; } @@ -332,20 +329,20 @@ public class Roles { if (preferredActivities == null) { preferredActivities = Collections.emptyList(); } - return new Role(name, exclusive, requiredComponents, permissions, appOps, + return new Role(name, labelResource, exclusive, requiredComponents, permissions, appOps, preferredActivities); } @NonNull - private static List parseRequiredComponents(@NonNull XmlPullParser parser) - throws IOException, XmlPullParserException { + private static List parseRequiredComponents( + @NonNull XmlResourceParser parser) throws IOException, XmlPullParserException { List requiredComponents = new ArrayList<>(); int outerDepth = parser.getDepth(); int type; - while ((type = parser.next()) != XmlPullParser.END_DOCUMENT - && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { - if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { + while ((type = parser.next()) != XmlResourceParser.END_DOCUMENT + && (type != XmlResourceParser.END_TAG || parser.getDepth() > outerDepth)) { + if (type == XmlResourceParser.END_TAG || type == XmlResourceParser.TEXT) { continue; } @@ -374,16 +371,16 @@ public class Roles { } @Nullable - private static RequiredComponent parseRequiredComponent(@NonNull XmlPullParser parser, + private static RequiredComponent parseRequiredComponent(@NonNull XmlResourceParser parser, @NonNull String name) throws IOException, XmlPullParserException { String permission = getAttributeValue(parser, ATTRIBUTE_PERMISSION); IntentFilterData intentFilterData = null; int outerDepth = parser.getDepth(); int type; - while ((type = parser.next()) != XmlPullParser.END_DOCUMENT - && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { - if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { + while ((type = parser.next()) != XmlResourceParser.END_DOCUMENT + && (type != XmlResourceParser.END_TAG || parser.getDepth() > outerDepth)) { + if (type == XmlResourceParser.END_TAG || type == XmlResourceParser.TEXT) { continue; } @@ -420,7 +417,7 @@ public class Roles { } @Nullable - private static IntentFilterData parseIntentFilterData(@NonNull XmlPullParser parser) + private static IntentFilterData parseIntentFilterData(@NonNull XmlResourceParser parser) throws IOException, XmlPullParserException { String action = null; List categories = new ArrayList<>(); @@ -430,9 +427,9 @@ public class Roles { int outerDepth = parser.getDepth(); int type; - while ((type = parser.next()) != XmlPullParser.END_DOCUMENT - && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { - if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { + while ((type = parser.next()) != XmlResourceParser.END_DOCUMENT + && (type != XmlResourceParser.END_TAG || parser.getDepth() > outerDepth)) { + if (type == XmlResourceParser.END_TAG || type == XmlResourceParser.TEXT) { continue; } @@ -501,16 +498,16 @@ public class Roles { } @NonNull - private static List parsePermissions(@NonNull XmlPullParser parser, + private static List parsePermissions(@NonNull XmlResourceParser parser, @NonNull Map permissionSets) throws IOException, XmlPullParserException { List permissions = new ArrayList<>(); int outerDepth = parser.getDepth(); int type; - while ((type = parser.next()) != XmlPullParser.END_DOCUMENT - && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { - if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { + while ((type = parser.next()) != XmlResourceParser.END_DOCUMENT + && (type != XmlResourceParser.END_TAG || parser.getDepth() > outerDepth)) { + if (type == XmlResourceParser.END_TAG || type == XmlResourceParser.TEXT) { continue; } @@ -550,16 +547,16 @@ public class Roles { } @NonNull - private static List parseAppOps(@NonNull XmlPullParser parser) throws IOException, + private static List parseAppOps(@NonNull XmlResourceParser parser) throws IOException, XmlPullParserException { List appOpNames = new ArrayList<>(); List appOps = new ArrayList<>(); int outerDepth = parser.getDepth(); int type; - while ((type = parser.next()) != XmlPullParser.END_DOCUMENT - && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { - if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { + while ((type = parser.next()) != XmlResourceParser.END_DOCUMENT + && (type != XmlResourceParser.END_TAG || parser.getDepth() > outerDepth)) { + if (type == XmlResourceParser.END_TAG || type == XmlResourceParser.TEXT) { continue; } @@ -600,15 +597,15 @@ public class Roles { } @NonNull - private static List parsePreferredActivities(@NonNull XmlPullParser parser) - throws IOException, XmlPullParserException { + private static List parsePreferredActivities( + @NonNull XmlResourceParser parser) throws IOException, XmlPullParserException { List preferredActivities = new ArrayList<>(); int outerDepth = parser.getDepth(); int type; - while ((type = parser.next()) != XmlPullParser.END_DOCUMENT - && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { - if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { + while ((type = parser.next()) != XmlResourceParser.END_DOCUMENT + && (type != XmlResourceParser.END_TAG || parser.getDepth() > outerDepth)) { + if (type == XmlResourceParser.END_TAG || type == XmlResourceParser.TEXT) { continue; } @@ -630,16 +627,16 @@ public class Roles { } @Nullable - private static PreferredActivity parsePreferredActivity(@NonNull XmlPullParser parser) + private static PreferredActivity parsePreferredActivity(@NonNull XmlResourceParser parser) throws IOException, XmlPullParserException { RequiredActivity activity = null; List intentFilterDatas = new ArrayList<>(); int outerDepth = parser.getDepth(); int type; - while ((type = parser.next()) != XmlPullParser.END_DOCUMENT - && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { - if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { + while ((type = parser.next()) != XmlResourceParser.END_DOCUMENT + && (type != XmlResourceParser.END_TAG || parser.getDepth() > outerDepth)) { + if (type == XmlResourceParser.END_TAG || type == XmlResourceParser.TEXT) { continue; } @@ -678,24 +675,25 @@ public class Roles { return new PreferredActivity(activity, intentFilterDatas); } - private static void skipCurrentTag(@NonNull XmlPullParser parser) throws XmlPullParserException, - IOException { + private static void skipCurrentTag(@NonNull XmlResourceParser parser) + throws XmlPullParserException, IOException { int outerDepth = parser.getDepth(); int type; - while ((type = parser.next()) != XmlPullParser.END_DOCUMENT - && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { + while ((type = parser.next()) != XmlResourceParser.END_DOCUMENT + && (type != XmlResourceParser.END_TAG || parser.getDepth() > outerDepth)) { // Do nothing } } @Nullable - private static String getAttributeValue(@NonNull XmlPullParser parser, @NonNull String name) { + private static String getAttributeValue(@NonNull XmlResourceParser parser, + @NonNull String name) { return parser.getAttributeValue(null, name); } @Nullable - private static String requireAttributeValue(@NonNull XmlPullParser parser, @NonNull String name, - @NonNull String tagName) { + private static String requireAttributeValue(@NonNull XmlResourceParser parser, + @NonNull String name, @NonNull String tagName) { String value = getAttributeValue(parser, name); if (value == null) { throwOrLogMessage("Missing attribute \"" + name + "\" on <" + tagName + ">"); @@ -703,6 +701,36 @@ public class Roles { return value; } + private static boolean getAttributeBooleanValue(@NonNull XmlResourceParser parser, + @NonNull String name, boolean defaultValue) { + return parser.getAttributeBooleanValue(null, name, defaultValue); + } + + @Nullable + private static Boolean requireAttributeBooleanValue(@NonNull XmlResourceParser parser, + @NonNull String name, boolean defaultValue, @NonNull String tagName) { + String value = requireAttributeValue(parser, name, tagName); + if (value == null) { + return null; + } + return getAttributeBooleanValue(parser, name, defaultValue); + } + + private static int getAttributeResourceValue(@NonNull XmlResourceParser parser, + @NonNull String name, int defaultValue) { + return parser.getAttributeResourceValue(null, name, defaultValue); + } + + @Nullable + private static Integer requireAttributeResourceValue(@NonNull XmlResourceParser parser, + @NonNull String name, int defaultValue, @NonNull String tagName) { + String value = requireAttributeValue(parser, name, tagName); + if (value == null) { + return null; + } + return getAttributeResourceValue(parser, name, defaultValue); + } + private static void throwOrLogMessage(String message) { if (DEBUG) { throw new IllegalArgumentException(message); @@ -719,7 +747,7 @@ public class Roles { } } - private static void throwOrLogForUnknownTag(@NonNull XmlPullParser parser) { + private static void throwOrLogForUnknownTag(@NonNull XmlResourceParser parser) { throwOrLogMessage("Unknown tag: " + parser.getName()); } diff --git a/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java b/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java index 97d463c75..486f4d1d9 100644 --- a/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java +++ b/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java @@ -92,8 +92,7 @@ public class RequestRoleFragment extends DialogFragment { finish(); return super.onCreateDialog(savedInstanceState); } - // FIXME: STOPSHIP: Add a label for role. - String roleLabel = role.getName(); + String roleLabel = getString(role.getLabelResource()); ApplicationInfo applicationInfo = PackageUtils.getApplicationInfo(mPackageName, context); if (applicationInfo == null) { -- GitLab From a6bb2b6eae469c25834c40660b8763f60d25394c Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Wed, 14 Nov 2018 10:53:32 -0800 Subject: [PATCH 136/701] Support meta data requirement for role's required components. This change adds support for meta data requirement for role's required components. Currently the implementation only supports boolean value. Bug: 110557011 Test: build Change-Id: I37418f526fb998204d825c16bc776f8c53be0e0b --- .../role/model/RequiredActivity.java | 19 ++- .../role/model/RequiredBroadcastReceiver.java | 19 ++- .../role/model/RequiredComponent.java | 115 ++++++++++++++---- .../role/model/RequiredContentProvider.java | 19 ++- .../role/model/RequiredService.java | 19 ++- .../packageinstaller/role/model/Roles.java | 52 +++++--- 6 files changed, 181 insertions(+), 62 deletions(-) diff --git a/src/com/android/packageinstaller/role/model/RequiredActivity.java b/src/com/android/packageinstaller/role/model/RequiredActivity.java index 03ae01d43..85403ac20 100644 --- a/src/com/android/packageinstaller/role/model/RequiredActivity.java +++ b/src/com/android/packageinstaller/role/model/RequiredActivity.java @@ -21,6 +21,8 @@ import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import android.os.Bundle; +import android.util.ArrayMap; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -32,18 +34,17 @@ import java.util.List; */ public class RequiredActivity extends RequiredComponent { - public RequiredActivity(@Nullable String permission, - @NonNull IntentFilterData intentFilterData) { - super(permission, intentFilterData); + public RequiredActivity(@NonNull IntentFilterData intentFilterData, + @Nullable String permission, @NonNull ArrayMap metaData) { + super(intentFilterData, permission, metaData); } @NonNull @Override - protected List queryIntentComponents(@NonNull Intent intent, + protected List queryIntentComponents(@NonNull Intent intent, int flags, @NonNull Context context) { PackageManager packageManager = context.getPackageManager(); - return packageManager.queryIntentActivities(intent, PackageManager.MATCH_DIRECT_BOOT_AWARE - | PackageManager.MATCH_DIRECT_BOOT_UNAWARE); + return packageManager.queryIntentActivities(intent, flags); } @NonNull @@ -58,4 +59,10 @@ public class RequiredActivity extends RequiredComponent { protected String getComponentPermission(@NonNull ResolveInfo resolveInfo) { return resolveInfo.activityInfo.permission; } + + @Nullable + @Override + protected Bundle getComponentMetaData(@NonNull ResolveInfo resolveInfo) { + return resolveInfo.activityInfo.metaData; + } } diff --git a/src/com/android/packageinstaller/role/model/RequiredBroadcastReceiver.java b/src/com/android/packageinstaller/role/model/RequiredBroadcastReceiver.java index 983424fbe..101119d2f 100644 --- a/src/com/android/packageinstaller/role/model/RequiredBroadcastReceiver.java +++ b/src/com/android/packageinstaller/role/model/RequiredBroadcastReceiver.java @@ -21,6 +21,8 @@ import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import android.os.Bundle; +import android.util.ArrayMap; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -32,18 +34,17 @@ import java.util.List; */ public class RequiredBroadcastReceiver extends RequiredComponent { - public RequiredBroadcastReceiver(@Nullable String permission, - @NonNull IntentFilterData intentFilterData) { - super(permission, intentFilterData); + public RequiredBroadcastReceiver(@NonNull IntentFilterData intentFilterData, + @Nullable String permission, @NonNull ArrayMap metaData) { + super(intentFilterData, permission, metaData); } @NonNull @Override - protected List queryIntentComponents(@NonNull Intent intent, + protected List queryIntentComponents(@NonNull Intent intent, int flags, @NonNull Context context) { PackageManager packageManager = context.getPackageManager(); - return packageManager.queryBroadcastReceivers(intent, PackageManager.MATCH_DIRECT_BOOT_AWARE - | PackageManager.MATCH_DIRECT_BOOT_UNAWARE); + return packageManager.queryBroadcastReceivers(intent, flags); } @NonNull @@ -58,4 +59,10 @@ public class RequiredBroadcastReceiver extends RequiredComponent { protected String getComponentPermission(@NonNull ResolveInfo resolveInfo) { return resolveInfo.activityInfo.permission; } + + @Nullable + @Override + protected Bundle getComponentMetaData(@NonNull ResolveInfo resolveInfo) { + return resolveInfo.activityInfo.metaData; + } } diff --git a/src/com/android/packageinstaller/role/model/RequiredComponent.java b/src/com/android/packageinstaller/role/model/RequiredComponent.java index 852c28131..207857bc0 100644 --- a/src/com/android/packageinstaller/role/model/RequiredComponent.java +++ b/src/com/android/packageinstaller/role/model/RequiredComponent.java @@ -19,7 +19,10 @@ package com.android.packageinstaller.role.model; import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import android.os.Bundle; +import android.util.ArrayMap; import android.util.ArraySet; import androidx.annotation.NonNull; @@ -34,22 +37,39 @@ import java.util.Objects; */ public abstract class RequiredComponent { + /** + * The {@code Intent} or {@code IntentFilter} data to match the components. + */ + @NonNull + private final IntentFilterData mIntentFilterData; + /** * Optional permission required on a component for match to succeed. + * + * @see android.content.pm.ActivityInfo#permission + * @see android.content.pm.ServiceInfo#permission */ @Nullable private final String mPermission; /** - * The {@code Intent} or {@code IntentFilter} data to match the components. + * The meta data required on a component for match to succeed. + * + * @see android.content.pm.PackageItemInfo#metaData */ @NonNull - private final IntentFilterData mIntentFilterData; + private final ArrayMap mMetaData; - public RequiredComponent(@Nullable String permission, - @NonNull IntentFilterData intentFilterData) { - mPermission = permission; + public RequiredComponent(@NonNull IntentFilterData intentFilterData, + @Nullable String permission, @NonNull ArrayMap metaData) { mIntentFilterData = intentFilterData; + mPermission = permission; + mMetaData = metaData; + } + + @NonNull + public IntentFilterData getIntentFilterData() { + return mIntentFilterData; } @Nullable @@ -58,8 +78,8 @@ public abstract class RequiredComponent { } @NonNull - public IntentFilterData getIntentFilterData() { - return mIntentFilterData; + public ArrayMap getMetaData() { + return mMetaData; } /** @@ -100,23 +120,59 @@ public abstract class RequiredComponent { if (packageName != null) { intent.setPackage(packageName); } - List resolveInfos = queryIntentComponents(intent, context); + int flags = PackageManager.MATCH_DIRECT_BOOT_AWARE + | PackageManager.MATCH_DIRECT_BOOT_UNAWARE; + boolean hasMetaData = !mMetaData.isEmpty(); + if (hasMetaData) { + flags |= PackageManager.GET_META_DATA; + } + List resolveInfos = queryIntentComponents(intent, flags, context); ArraySet componentPackageNames = new ArraySet<>(); List componentNames = new ArrayList<>(); int resolveInfosSize = resolveInfos.size(); - for (int i = 0; i < resolveInfosSize; i++) { - ResolveInfo resolveInfo = resolveInfos.get(i); - if (mPermission == null || Objects.equals(getComponentPermission(resolveInfo), - mPermission)) { - ComponentName componentName = getComponentComponentName(resolveInfo); - String componentPackageName = componentName.getPackageName(); - if (componentPackageNames.contains(componentPackageName)) { + for (int resolveInfosIndex = 0; resolveInfosIndex < resolveInfosSize; resolveInfosIndex++) { + ResolveInfo resolveInfo = resolveInfos.get(resolveInfosIndex); + + if (mPermission != null) { + String componentPermission = getComponentPermission(resolveInfo); + if (!Objects.equals(componentPermission, mPermission)) { + continue; + } + } + + if (hasMetaData) { + Bundle componentMetaData = getComponentMetaData(resolveInfo); + if (componentMetaData == null) { + continue; + } + int metaDataSize = mMetaData.size(); + if (componentMetaData.size() < metaDataSize) { + continue; + } + boolean containsAllMetaData = true; + for (int metaDataIndex = 0; metaDataIndex < metaDataSize; metaDataIndex++) { + String metaDataName = mMetaData.keyAt(metaDataIndex); + Object metaDataValue = mMetaData.valueAt(metaDataIndex); + Object componentMetaDataValue = componentMetaData.get(metaDataName); + if (!Objects.equals(componentMetaDataValue, metaDataValue)) { + containsAllMetaData = false; + break; + } + } + if (!containsAllMetaData) { continue; } - componentPackageNames.add(componentPackageName); - componentNames.add(componentName); } + + ComponentName componentName = getComponentComponentName(resolveInfo); + String componentPackageName = componentName.getPackageName(); + if (componentPackageNames.contains(componentPackageName)) { + continue; + } + + componentPackageNames.add(componentPackageName); + componentNames.add(componentName); } return componentNames; } @@ -126,12 +182,13 @@ public abstract class RequiredComponent { * to worst. * * @param intent the {@code Intent} to match against + * @param flags the flags to be used for this query * @param context the {@code Context} to retrieve system services * * @return the list of matching components */ @NonNull - protected abstract List queryIntentComponents(@NonNull Intent intent, + protected abstract List queryIntentComponents(@NonNull Intent intent, int flags, @NonNull Context context); /** @@ -154,11 +211,22 @@ public abstract class RequiredComponent { @Nullable protected abstract String getComponentPermission(@NonNull ResolveInfo resolveInfo); + /** + * Get the meta data associated with a component. + * + * @param resolveInfo the {@code ResolveInfo} of the component + * + * @return the meta data associated with a component + */ + @Nullable + protected abstract Bundle getComponentMetaData(@NonNull ResolveInfo resolveInfo); + @Override public String toString() { return "RequiredComponent{" - + "mPermission='" + mPermission + '\'' - + ", mIntentFilterData=" + mIntentFilterData + + "mIntentFilterData=" + mIntentFilterData + + ", mPermission='" + mPermission + '\'' + + ", mMetaData=" + mMetaData + '}'; } @@ -171,12 +239,13 @@ public abstract class RequiredComponent { return false; } RequiredComponent that = (RequiredComponent) object; - return Objects.equals(mPermission, that.mPermission) - && Objects.equals(mIntentFilterData, that.mIntentFilterData); + return Objects.equals(mIntentFilterData, that.mIntentFilterData) + && Objects.equals(mPermission, that.mPermission) + && Objects.equals(mMetaData, that.mMetaData); } @Override public int hashCode() { - return Objects.hash(mPermission, mIntentFilterData); + return Objects.hash(mIntentFilterData, mPermission, mMetaData); } } diff --git a/src/com/android/packageinstaller/role/model/RequiredContentProvider.java b/src/com/android/packageinstaller/role/model/RequiredContentProvider.java index b454f839e..dc781beab 100644 --- a/src/com/android/packageinstaller/role/model/RequiredContentProvider.java +++ b/src/com/android/packageinstaller/role/model/RequiredContentProvider.java @@ -21,6 +21,8 @@ import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import android.os.Bundle; +import android.util.ArrayMap; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -32,18 +34,17 @@ import java.util.List; */ public class RequiredContentProvider extends RequiredComponent { - public RequiredContentProvider(@Nullable String permission, - @NonNull IntentFilterData intentFilterData) { - super(permission, intentFilterData); + public RequiredContentProvider(@NonNull IntentFilterData intentFilterData, + @Nullable String permission, @NonNull ArrayMap metaData) { + super(intentFilterData, permission, metaData); } @NonNull @Override - protected List queryIntentComponents(@NonNull Intent intent, + protected List queryIntentComponents(@NonNull Intent intent, int flags, @NonNull Context context) { PackageManager packageManager = context.getPackageManager(); - return packageManager.queryIntentContentProviders(intent, - PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE); + return packageManager.queryIntentContentProviders(intent, flags); } @NonNull @@ -60,4 +61,10 @@ public class RequiredContentProvider extends RequiredComponent { //return resolveInfo.providerInfo.readPermission; throw new UnsupportedOperationException(); } + + @Nullable + @Override + protected Bundle getComponentMetaData(@NonNull ResolveInfo resolveInfo) { + return resolveInfo.providerInfo.metaData; + } } diff --git a/src/com/android/packageinstaller/role/model/RequiredService.java b/src/com/android/packageinstaller/role/model/RequiredService.java index 1bfaa3a22..d0d90e50f 100644 --- a/src/com/android/packageinstaller/role/model/RequiredService.java +++ b/src/com/android/packageinstaller/role/model/RequiredService.java @@ -21,6 +21,8 @@ import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import android.os.Bundle; +import android.util.ArrayMap; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -32,18 +34,17 @@ import java.util.List; */ public class RequiredService extends RequiredComponent { - public RequiredService(@Nullable String permission, - @NonNull IntentFilterData intentFilterData) { - super(permission, intentFilterData); + public RequiredService(@NonNull IntentFilterData intentFilterData, + @Nullable String permission, @NonNull ArrayMap metaData) { + super(intentFilterData, permission, metaData); } @NonNull @Override - protected List queryIntentComponents(@NonNull Intent intent, + protected List queryIntentComponents(@NonNull Intent intent, int flags, @NonNull Context context) { PackageManager packageManager = context.getPackageManager(); - return packageManager.queryIntentServices(intent, PackageManager.MATCH_DIRECT_BOOT_AWARE - | PackageManager.MATCH_DIRECT_BOOT_UNAWARE); + return packageManager.queryIntentServices(intent, flags); } @NonNull @@ -57,4 +58,10 @@ public class RequiredService extends RequiredComponent { protected String getComponentPermission(@NonNull ResolveInfo resolveInfo) { return resolveInfo.serviceInfo.permission; } + + @Nullable + @Override + protected Bundle getComponentMetaData(@NonNull ResolveInfo resolveInfo) { + return resolveInfo.serviceInfo.metaData; + } } diff --git a/src/com/android/packageinstaller/role/model/Roles.java b/src/com/android/packageinstaller/role/model/Roles.java index 9e0c84231..0f319f9ba 100644 --- a/src/com/android/packageinstaller/role/model/Roles.java +++ b/src/com/android/packageinstaller/role/model/Roles.java @@ -52,6 +52,7 @@ public class Roles { private static final String TAG_ROLES = "roles"; private static final String TAG_PERMISSION_SET = "permission-set"; + private static final String TAG_PERMISSION = "permission"; private static final String TAG_ROLE = "role"; private static final String TAG_REQUIRED_COMPONENTS = "required-components"; private static final String TAG_ACTIVITY = "activity"; @@ -62,18 +63,19 @@ public class Roles { private static final String TAG_ACTION = "action"; private static final String TAG_CATEGORY = "category"; private static final String TAG_DATA = "data"; + private static final String TAG_META_DATA = "meta-data"; private static final String TAG_PERMISSIONS = "permissions"; - private static final String TAG_PERMISSION = "permission"; private static final String TAG_APP_OPS = "app-ops"; private static final String TAG_APP_OP = "app-op"; private static final String TAG_PREFERRED_ACTIVITIES = "preferred-activites"; private static final String TAG_PREFERRED_ACTIVITY = "preferred-activity"; private static final String ATTRIBUTE_NAME = "name"; + private static final String ATTRIBUTE_PERMISSION = "permission"; private static final String ATTRIBUTE_EXCLUSIVE = "exclusive"; private static final String ATTRIBUTE_LABEL = "label"; - private static final String ATTRIBUTE_PERMISSION = "permission"; private static final String ATTRIBUTE_SCHEME = "scheme"; private static final String ATTRIBUTE_MIME_TYPE = "mimeType"; + private static final String ATTRIBUTE_VALUE = "value"; private static final String ATTRIBUTE_MODE = "mode"; private static final String MODE_NAME_ALLOWED = "allowed"; @@ -375,6 +377,7 @@ public class Roles { @NonNull String name) throws IOException, XmlPullParserException { String permission = getAttributeValue(parser, ATTRIBUTE_PERMISSION); IntentFilterData intentFilterData = null; + ArrayMap metaData = new ArrayMap<>(); int outerDepth = parser.getDepth(); int type; @@ -384,16 +387,35 @@ public class Roles { continue; } - if (parser.getName().equals(TAG_INTENT_FILTER)) { - if (intentFilterData != null) { - throwOrLogMessage("Duplicate in <" + name + ">"); + switch (parser.getName()) { + case TAG_INTENT_FILTER: + if (intentFilterData != null) { + throwOrLogMessage("Duplicate in <" + name + ">"); + skipCurrentTag(parser); + continue; + } + intentFilterData = parseIntentFilterData(parser); + break; + case TAG_META_DATA: + String metaDataName = requireAttributeValue(parser, ATTRIBUTE_NAME, + TAG_META_DATA); + if (metaDataName == null) { + continue; + } + checkDuplicateElement(metaDataName, metaData.keySet(), "meta data"); + // HACK: Only support boolean for now. + // TODO: Support android:resource and other types of android:value, maybe by + // switching to TypedArray and styleables. + Boolean metaDataValue = requireAttributeBooleanValue(parser, ATTRIBUTE_VALUE, + false, TAG_META_DATA); + if (metaDataValue == null) { + continue; + } + metaData.put(metaDataName, metaDataValue); + break; + default: + throwOrLogForUnknownTag(parser); skipCurrentTag(parser); - continue; - } - intentFilterData = parseIntentFilterData(parser); - } else { - throwOrLogForUnknownTag(parser); - skipCurrentTag(parser); } } @@ -403,13 +425,13 @@ public class Roles { } switch (name) { case TAG_ACTIVITY: - return new RequiredActivity(permission, intentFilterData); + return new RequiredActivity(intentFilterData, permission, metaData); case TAG_PROVIDER: - return new RequiredContentProvider(permission, intentFilterData); + return new RequiredContentProvider(intentFilterData, permission, metaData); case TAG_RECEIVER: - return new RequiredBroadcastReceiver(permission, intentFilterData); + return new RequiredBroadcastReceiver(intentFilterData, permission, metaData); case TAG_SERVICE: - return new RequiredService(permission, intentFilterData); + return new RequiredService(intentFilterData, permission, metaData); default: throwOrLogMessage("Unknown tag <" + name + ">"); return null; -- GitLab From 34f4ccc246040118d5f2d4e300f42d20edc7d4d2 Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Thu, 15 Nov 2018 08:45:46 -0800 Subject: [PATCH 137/701] Add test mapping to permission controller We should also add the PermissionHostTest once bug 119576878 is fixed. Test: atest --test-mapping packages/apps/PermissionController:presubmit Change-Id: I98f1e184256d4f969ea283d9bf20fa2051b73a16 --- TEST_MAPPING | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 TEST_MAPPING diff --git a/TEST_MAPPING b/TEST_MAPPING new file mode 100644 index 000000000..6f8a76eba --- /dev/null +++ b/TEST_MAPPING @@ -0,0 +1,15 @@ +{ + "presubmit": [ + { + "name": "CtsPermissionTestCases", + "options": [ + { + "include-filter": "android.permission.cts.BackgroundPermissionsTest" + }, + { + "include-filter": "android.permission.cts.PermissionGroupChange" + } + ] + } + ] +} \ No newline at end of file -- GitLab From e137313824ad0821f41ce136522e56d756fccbab Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Wed, 14 Nov 2018 17:02:28 -0800 Subject: [PATCH 138/701] Hard code permission->group mapping into PermissionsController The platform does not define the mapping anymore. We can now change the mapping in an update of this app by modifying the hard coded table. Test: atest CtsAppSecurityHostTestCases:android.appsecurity.cts.PermissionsHostTest atest --test-mapping packages/apps/PermissionController:presubmit Change-Id: Ia8bd8c52c62304a235f68fac5c45204c0e8bcc93 --- .../permission/model/AppPermissionGroup.java | 11 +- .../permission/model/PermissionApps.java | 2 +- .../permission/model/PermissionGroups.java | 2 +- .../handheld/AllAppPermissionsFragment.java | 2 +- .../television/AllAppPermissionsFragment.java | 5 +- .../permission/utils/Utils.java | 197 ++++++++++++++++-- .../role/model/Permissions.java | 5 +- 7 files changed, 189 insertions(+), 35 deletions(-) diff --git a/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java b/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java index 1c70935dd..8ac6123d9 100644 --- a/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java +++ b/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java @@ -38,6 +38,7 @@ import androidx.annotation.StringRes; import com.android.packageinstaller.permission.utils.ArrayUtils; import com.android.packageinstaller.permission.utils.LocationUtils; +import com.android.packageinstaller.permission.utils.Utils; import com.android.permissioncontroller.R; import java.lang.reflect.InvocationTargetException; @@ -122,11 +123,11 @@ public final class AppPermissionGroup implements Comparable return null; } + String group = Utils.getGroupOfPermission(permissionInfo); PackageItemInfo groupInfo = permissionInfo; - if (permissionInfo.group != null) { + if (group != null) { try { - groupInfo = context.getPackageManager().getPermissionGroupInfo( - permissionInfo.group, 0); + groupInfo = context.getPackageManager().getPermissionGroupInfo(group, 0); } catch (PackageManager.NameNotFoundException e) { /* ignore */ } @@ -135,8 +136,8 @@ public final class AppPermissionGroup implements Comparable List permissionInfos = null; if (groupInfo instanceof PermissionGroupInfo) { try { - permissionInfos = context.getPackageManager().queryPermissionsByGroup( - groupInfo.name, 0); + permissionInfos = Utils.getPermissionInfosForGroup(context.getPackageManager(), + groupInfo.name); } catch (PackageManager.NameNotFoundException e) { /* ignore */ } diff --git a/src/com/android/packageinstaller/permission/model/PermissionApps.java b/src/com/android/packageinstaller/permission/model/PermissionApps.java index b5e19915c..7e477c1ad 100644 --- a/src/com/android/packageinstaller/permission/model/PermissionApps.java +++ b/src/com/android/packageinstaller/permission/model/PermissionApps.java @@ -260,7 +260,7 @@ public class PermissionApps { private List getGroupPermissionInfos(String groupName) { try { - return mContext.getPackageManager().queryPermissionsByGroup(groupName, 0); + return Utils.getPermissionInfosForGroup(mContext.getPackageManager(), groupName); } catch (NameNotFoundException e) { /* ignore */ } diff --git a/src/com/android/packageinstaller/permission/model/PermissionGroups.java b/src/com/android/packageinstaller/permission/model/PermissionGroups.java index 87f1349b0..257d36e9c 100644 --- a/src/com/android/packageinstaller/permission/model/PermissionGroups.java +++ b/src/com/android/packageinstaller/permission/model/PermissionGroups.java @@ -155,7 +155,7 @@ public final class PermissionGroups implements LoaderCallbacks groupPermissions; try { - groupPermissions = packageManager.queryPermissionsByGroup(groupInfo.name, 0); + groupPermissions = Utils.getPermissionInfosForGroup(packageManager, groupInfo.name); } catch (PackageManager.NameNotFoundException e) { continue; } diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AllAppPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AllAppPermissionsFragment.java index e3f5e4292..e004a01f0 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AllAppPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AllAppPermissionsFragment.java @@ -171,7 +171,7 @@ public final class AllAppPermissionsFragment extends SettingsWithHeader { if ((perm.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE) == PermissionInfo.PROTECTION_DANGEROUS) { - PackageItemInfo group = getGroup(perm.group, pm); + PackageItemInfo group = getGroup(Utils.getGroupOfPermission(perm), pm); if (group == null) { group = perm; } diff --git a/src/com/android/packageinstaller/permission/ui/television/AllAppPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/television/AllAppPermissionsFragment.java index 577197883..dcbef43ab 100644 --- a/src/com/android/packageinstaller/permission/ui/television/AllAppPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/television/AllAppPermissionsFragment.java @@ -43,10 +43,10 @@ import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceGroup; import androidx.preference.SwitchPreference; -import com.android.permissioncontroller.R; import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.model.AppPermissions; import com.android.packageinstaller.permission.utils.Utils; +import com.android.permissioncontroller.R; import java.util.ArrayList; import java.util.Collections; @@ -167,8 +167,7 @@ public final class AllAppPermissionsFragment extends SettingsWithHeader { continue; } - - PermissionGroupInfo group = getGroup(perm.group, pm); + PermissionGroupInfo group = getGroup(Utils.getGroupOfPermission(perm), pm); if ((perm.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE) == PermissionInfo.PROTECTION_DANGEROUS) { PreferenceGroup pref = findOrCreate(group != null ? group : perm, pm, prefs); diff --git a/src/com/android/packageinstaller/permission/utils/Utils.java b/src/com/android/packageinstaller/permission/utils/Utils.java index 78a97784b..388ff6f67 100644 --- a/src/com/android/packageinstaller/permission/utils/Utils.java +++ b/src/com/android/packageinstaller/permission/utils/Utils.java @@ -16,22 +16,39 @@ package com.android.packageinstaller.permission.utils; +import static android.Manifest.permission_group.ACTIVITY_RECOGNITION; +import static android.Manifest.permission_group.CALENDAR; +import static android.Manifest.permission_group.CALL_LOG; +import static android.Manifest.permission_group.CAMERA; +import static android.Manifest.permission_group.CONTACTS; +import static android.Manifest.permission_group.LOCATION; +import static android.Manifest.permission_group.MEDIA_AURAL; +import static android.Manifest.permission_group.MEDIA_VISUAL; +import static android.Manifest.permission_group.MICROPHONE; +import static android.Manifest.permission_group.PHONE; +import static android.Manifest.permission_group.SENSORS; +import static android.Manifest.permission_group.SMS; +import static android.Manifest.permission_group.STORAGE; + import android.Manifest; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; +import android.content.pm.PermissionInfo; import android.content.pm.ResolveInfo; import android.content.res.Resources; import android.content.res.Resources.Theme; import android.graphics.drawable.Drawable; import android.text.Html; import android.text.TextUtils; +import android.util.ArrayMap; import android.util.ArraySet; import android.util.Log; import android.util.TypedValue; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.annotation.StringRes; import androidx.core.text.BidiFormatter; @@ -40,6 +57,8 @@ import com.android.packageinstaller.permission.model.AppPermissions; import com.android.packageinstaller.permission.model.PermissionApps.PermissionApp; import com.android.permissioncontroller.R; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; public final class Utils { @@ -50,29 +69,168 @@ public final class Utils { public static final float DEFAULT_MAX_LABEL_SIZE_PX = 500f; - public static final String[] MODERN_PERMISSION_GROUPS = { - Manifest.permission_group.ACTIVITY_RECOGNITION, - Manifest.permission_group.CALENDAR, - Manifest.permission_group.CALL_LOG, - Manifest.permission_group.CAMERA, - Manifest.permission_group.CONTACTS, - Manifest.permission_group.LOCATION, - Manifest.permission_group.SENSORS, - Manifest.permission_group.SMS, - Manifest.permission_group.PHONE, - Manifest.permission_group.MICROPHONE, - Manifest.permission_group.STORAGE, - Manifest.permission_group.MEDIA_AURAL, - Manifest.permission_group.MEDIA_VISUAL, - }; + /** Mapping permission -> group for all dangerous platform permissions */ + private static final ArrayMap PLATFORM_PERMISSIONS; + + /** Mapping group -> permissions for all dangerous platform permissions */ + private static final ArrayMap> PLATFORM_PERMISSION_GROUPS; private static final Intent LAUNCHER_INTENT = new Intent(Intent.ACTION_MAIN, null) - .addCategory(Intent.CATEGORY_LAUNCHER); + .addCategory(Intent.CATEGORY_LAUNCHER); + + static { + PLATFORM_PERMISSIONS = new ArrayMap<>(); + + PLATFORM_PERMISSIONS.put(Manifest.permission.READ_CONTACTS, CONTACTS); + PLATFORM_PERMISSIONS.put(Manifest.permission.WRITE_CONTACTS, CONTACTS); + PLATFORM_PERMISSIONS.put(Manifest.permission.GET_ACCOUNTS, CONTACTS); + + PLATFORM_PERMISSIONS.put(Manifest.permission.READ_CALENDAR, CALENDAR); + PLATFORM_PERMISSIONS.put(Manifest.permission.WRITE_CALENDAR, CALENDAR); + + PLATFORM_PERMISSIONS.put(Manifest.permission.SEND_SMS, SMS); + PLATFORM_PERMISSIONS.put(Manifest.permission.RECEIVE_SMS, SMS); + PLATFORM_PERMISSIONS.put(Manifest.permission.READ_SMS, SMS); + PLATFORM_PERMISSIONS.put(Manifest.permission.RECEIVE_MMS, SMS); + PLATFORM_PERMISSIONS.put(Manifest.permission.RECEIVE_WAP_PUSH, SMS); + PLATFORM_PERMISSIONS.put(Manifest.permission.READ_CELL_BROADCASTS, SMS); + + PLATFORM_PERMISSIONS.put(Manifest.permission.READ_EXTERNAL_STORAGE, STORAGE); + PLATFORM_PERMISSIONS.put(Manifest.permission.WRITE_EXTERNAL_STORAGE, STORAGE); + + PLATFORM_PERMISSIONS.put(Manifest.permission.READ_MEDIA_AUDIO, MEDIA_AURAL); + PLATFORM_PERMISSIONS.put(Manifest.permission.WRITE_MEDIA_AUDIO, MEDIA_AURAL); + + PLATFORM_PERMISSIONS.put(Manifest.permission.READ_MEDIA_IMAGES, MEDIA_VISUAL); + PLATFORM_PERMISSIONS.put(Manifest.permission.WRITE_MEDIA_IMAGES, MEDIA_VISUAL); + PLATFORM_PERMISSIONS.put(Manifest.permission.READ_MEDIA_VIDEO, MEDIA_VISUAL); + PLATFORM_PERMISSIONS.put(Manifest.permission.WRITE_MEDIA_VIDEO, MEDIA_VISUAL); + PLATFORM_PERMISSIONS.put(Manifest.permission.ACCESS_MEDIA_LOCATION, MEDIA_VISUAL); + + PLATFORM_PERMISSIONS.put(Manifest.permission.ACCESS_FINE_LOCATION, LOCATION); + PLATFORM_PERMISSIONS.put(Manifest.permission.ACCESS_COARSE_LOCATION, LOCATION); + PLATFORM_PERMISSIONS.put(Manifest.permission.ACCESS_BACKGROUND_LOCATION, LOCATION); + + PLATFORM_PERMISSIONS.put(Manifest.permission.READ_CALL_LOG, CALL_LOG); + PLATFORM_PERMISSIONS.put(Manifest.permission.WRITE_CALL_LOG, CALL_LOG); + PLATFORM_PERMISSIONS.put(Manifest.permission.PROCESS_OUTGOING_CALLS, CALL_LOG); + + PLATFORM_PERMISSIONS.put(Manifest.permission.READ_PHONE_STATE, PHONE); + PLATFORM_PERMISSIONS.put(Manifest.permission.READ_PHONE_NUMBERS, PHONE); + PLATFORM_PERMISSIONS.put(Manifest.permission.CALL_PHONE, PHONE); + PLATFORM_PERMISSIONS.put(Manifest.permission.ADD_VOICEMAIL, PHONE); + PLATFORM_PERMISSIONS.put(Manifest.permission.USE_SIP, PHONE); + PLATFORM_PERMISSIONS.put(Manifest.permission.ANSWER_PHONE_CALLS, PHONE); + PLATFORM_PERMISSIONS.put(Manifest.permission.ACCEPT_HANDOVER, PHONE); + + PLATFORM_PERMISSIONS.put(Manifest.permission.RECORD_AUDIO, MICROPHONE); + + PLATFORM_PERMISSIONS.put(Manifest.permission.ACTIVITY_RECOGNITION, ACTIVITY_RECOGNITION); + + PLATFORM_PERMISSIONS.put(Manifest.permission.CAMERA, CAMERA); + + PLATFORM_PERMISSIONS.put(Manifest.permission.BODY_SENSORS, SENSORS); + + PLATFORM_PERMISSION_GROUPS = new ArrayMap<>(); + int numPlatformPermissions = PLATFORM_PERMISSIONS.size(); + for (int i = 0; i < numPlatformPermissions; i++) { + String permission = PLATFORM_PERMISSIONS.keyAt(i); + String permissionGroup = PLATFORM_PERMISSIONS.valueAt(i); + + ArrayList permissionsOfThisGroup = PLATFORM_PERMISSION_GROUPS.get( + permissionGroup); + if (permissionsOfThisGroup == null) { + permissionsOfThisGroup = new ArrayList<>(); + PLATFORM_PERMISSION_GROUPS.put(permissionGroup, permissionsOfThisGroup); + } + + permissionsOfThisGroup.add(permission); + } + } private Utils() { /* do nothing - hide constructor */ } + /** + * Get permission group a platform permission belongs to. + * + * @param permission the permission to resolve + * + * @return The group the permission belongs to + */ + private static @Nullable String getGroupOfPlatformPermission(@NonNull String permission) { + return PLATFORM_PERMISSIONS.get(permission); + } + + /** + * Get name of the permission group a permission belongs to. + * + * @param permission the {@link PermissionInfo info} of the permission to resolve + * + * @return The group the permission belongs to + */ + public static @Nullable String getGroupOfPermission(@NonNull PermissionInfo permission) { + String groupName = permission.group; + if (groupName == null) { + groupName = Utils.getGroupOfPlatformPermission(permission.name); + } + + return groupName; + } + + /** + * Get the {@link PermissionInfo infos} for all platform permissions belonging to a group. + * + * @param pm Package manager to use to resolve permission infos + * @param group the group + * + * @return The infos for platform permissions belonging to the group or an empty list if the + * group is not does not have platform runtime permissions + */ + private static @NonNull List getPlatformPermissionsOfGroup( + @NonNull PackageManager pm, @NonNull String group) { + ArrayList permInfos = new ArrayList<>(); + + ArrayList permissions = PLATFORM_PERMISSION_GROUPS.get(group); + if (permissions == null) { + return Collections.emptyList(); + } + + int numPermissions = permissions.size(); + for (int i = 0; i < numPermissions; i++) { + String permName = permissions.get(i); + PermissionInfo permInfo; + try { + permInfo = pm.getPermissionInfo(permName, 0); + } catch (PackageManager.NameNotFoundException e) { + throw new IllegalStateException(permName + " not defined by platform", e); + } + + permInfos.add(permInfo); + } + + return permInfos; + } + + /** + * Get the {@link PermissionInfo infos} for all permission infos belonging to a group. + * + * @param pm Package manager to use to resolve permission infos + * @param group the group + * + * @return The infos of permissions belonging to the group or an empty list if the group is not + * does not have runtime permissions + */ + public static @NonNull List getPermissionInfosForGroup( + @NonNull PackageManager pm, @NonNull String group) + throws PackageManager.NameNotFoundException { + List permissions = pm.queryPermissionsByGroup(group, 0); + permissions.addAll(Utils.getPlatformPermissionsOfGroup(pm, group)); + + return permissions; + } + /** * Get the label for an application. * @@ -100,12 +258,7 @@ public final class Utils { } public static boolean isModernPermissionGroup(String name) { - for (String modernGroup : MODERN_PERMISSION_GROUPS) { - if (modernGroup.equals(name)) { - return true; - } - } - return false; + return PLATFORM_PERMISSION_GROUPS.containsKey(name); } /** diff --git a/src/com/android/packageinstaller/role/model/Permissions.java b/src/com/android/packageinstaller/role/model/Permissions.java index a5906fa3b..9436d8ee9 100644 --- a/src/com/android/packageinstaller/role/model/Permissions.java +++ b/src/com/android/packageinstaller/role/model/Permissions.java @@ -35,6 +35,7 @@ import androidx.annotation.Nullable; import com.android.packageinstaller.permission.utils.ArrayUtils; import com.android.packageinstaller.permission.utils.CollectionUtils; +import com.android.packageinstaller.permission.utils.Utils; import com.android.packageinstaller.role.utils.PackageUtils; import java.util.ArrayList; @@ -621,8 +622,8 @@ public class Permissions { List permissionInfos; try { - permissionInfos = packageManager.queryPermissionsByGroup(permissionGroupInfo.name, - 0); + permissionInfos = Utils.getPermissionInfosForGroup(packageManager, + permissionGroupInfo.name); } catch (PackageManager.NameNotFoundException e) { Log.e(LOG_TAG, "Cannot get permissions for group: " + permissionGroupInfo.name); continue; -- GitLab From 11d7ff119abeebae4826e5ebe162625c2a380e1e Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Thu, 15 Nov 2018 12:21:08 -0800 Subject: [PATCH 139/701] Replace hard-coded layout values with attributes and dimensions. Bug: 63532550 Test: Open the app permission screen. Change-Id: I5c42fa0397a8a83f0ffc3be65c765b0cee6ea633 --- res/layout/app_permission.xml | 74 +++++++++++++++++------------------ res/values/dimens.xml | 12 ++++++ res/values/styles.xml | 36 +++++++++++++++++ 3 files changed, 85 insertions(+), 37 deletions(-) create mode 100644 res/values/styles.xml diff --git a/res/layout/app_permission.xml b/res/layout/app_permission.xml index bfe0f7816..95f109b22 100644 --- a/res/layout/app_permission.xml +++ b/res/layout/app_permission.xml @@ -30,24 +30,22 @@ android:minHeight="?android:attr/listPreferredItemHeight" android:paddingStart="?android:attr/listPreferredItemPaddingStart" android:paddingEnd="?android:attr/listPreferredItemPaddingEnd" - android:background="?android:attr/selectableItemBackground" - android:theme="@*android:style/Theme.DeviceDefault.PermissionGrant"> + android:background="?android:attr/selectableItemBackground"> + android:textAppearance="?android:attr/textAppearanceSmall" /> + android:layout_height="wrap_content" > + style="@style/PermissionGrantRadioButton" /> + android:paddingTop="@dimen/app_permission_vertical_divider_padding_top" + android:paddingBottom="@dimen/app_permission_vertical_divider_padding_bottom"> + style="@style/PermissionGrantRadioButton" /> + style="@style/PermissionGrantRadioButton" /> @@ -109,7 +104,8 @@ android:id="@+id/permission_details" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginTop="16dp" /> + android:layout_marginStart="@dimen/app_permission_detail_margin_start" + android:layout_marginTop="@dimen/app_permission_detail_margin_top" />
@@ -117,29 +113,33 @@ android:id="@+id/divider" android:layout_width="match_parent" android:layout_height=".75dp" - android:layout_marginTop="20dp" - android:layout_marginBottom="8dp" + android:layout_marginTop="@dimen/app_permission_divider_margin_top" + android:layout_marginBottom="@dimen/app_permission_divider_margin_bottom" android:background="?android:attr/dividerHorizontal"/> - - - + android:orientation="vertical" + android:minHeight="?android:attr/listPreferredItemHeight" + android:paddingStart="?android:attr/listPreferredItemPaddingStart" + android:paddingEnd="?android:attr/listPreferredItemPaddingEnd" + android:background="?android:attr/selectableItemBackground"> + + + + + +
\ No newline at end of file diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 112723f48..7b856fe59 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -41,4 +41,16 @@ 8dp 24dp + + 48dp + 16dp + + 16dp + 16dp + + 12dp + 48dp + + 12dp + 8dp diff --git a/res/values/styles.xml b/res/values/styles.xml new file mode 100644 index 000000000..34b71d59f --- /dev/null +++ b/res/values/styles.xml @@ -0,0 +1,36 @@ + + + + + + + + + -- GitLab From ad74a27db6ad5b08dd59a2c57e2b17e9540ac65c Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Fri, 16 Nov 2018 11:25:08 -0800 Subject: [PATCH 140/701] Have AppPermissionFragment listen for changes to its package. Modify AppPermissionFragment to listen for permission changes and package uninstalls. If a permission changes, it changes the selected radio button. It the package is uninstalled, the activity exits. This also fixes PackageRemovalMonitor so that it properly receives uninstall events. Bug: 63532550 Test: Open page, adb revoke permission, see selected button change Test: Open page, adb uninstall app, see activity exit Test: Open page, return to home, adb uninstall app, switch back to page, see activity exit Change-Id: Ia9f080aaa323910c1c35ed648f8d6c8bbb1c6603 --- .../ui/handheld/AppPermissionFragment.java | 104 +++++++++++++++++- .../utils/PackageRemovalMonitor.java | 1 + 2 files changed, 101 insertions(+), 4 deletions(-) diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java index a903f3bed..0ae937cd8 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java @@ -28,6 +28,7 @@ import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.UserHandle; @@ -50,6 +51,7 @@ import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.model.AppPermissionUsage; import com.android.packageinstaller.permission.utils.IconDrawableFactory; import com.android.packageinstaller.permission.utils.LocationUtils; +import com.android.packageinstaller.permission.utils.PackageRemovalMonitor; import com.android.packageinstaller.permission.utils.Utils; import com.android.permissioncontroller.R; import com.android.settingslib.RestrictedLockUtils; @@ -85,6 +87,18 @@ public class AppPermissionFragment extends PermissionsFrameFragment { private boolean mHasConfirmedRevoke; + /** + * Listens for changes to the permission of the app the permission is currently getting + * granted to. {@code null} when unregistered. + */ + private @Nullable PackageManager.OnPermissionsChangedListener mPermissionChangeListener; + + /** + * Listens for changes to the app the permission is currently getting granted to. {@code null} + * when unregistered. + */ + private @Nullable PackageRemovalMonitor mPackageRemovalMonitor; + /** * @return A new fragment */ @@ -107,6 +121,16 @@ public class AppPermissionFragment extends PermissionsFrameFragment { ab.setDisplayHomeAsUpEnabled(true); } + mHasConfirmedRevoke = false; + + createAppPermissionGroup(); + + getActivity().setTitle( + getPreferenceManager().getContext().getString(R.string.app_permission_title, + mGroup.getLabel())); + } + + private void createAppPermissionGroup() { String packageName = getArguments().getString(Intent.EXTRA_PACKAGE_NAME); Activity activity = getActivity(); Context context = getPreferenceManager().getContext(); @@ -119,10 +143,6 @@ public class AppPermissionFragment extends PermissionsFrameFragment { activity.finish(); return; } - - mHasConfirmedRevoke = false; - - activity.setTitle(context.getString(R.string.app_permission_title, mGroup.getLabel())); } @Override @@ -171,6 +191,62 @@ public class AppPermissionFragment extends PermissionsFrameFragment { return root; } + @Override + public void onStart() { + super.onStart(); + + String packageName = getArguments().getString(Intent.EXTRA_PACKAGE_NAME); + Activity activity = getActivity(); + + // Get notified when permissions change. + try { + mPermissionChangeListener = new PermissionChangeListener( + mGroup.getApp().applicationInfo.uid); + } catch (NameNotFoundException e) { + activity.setResult(Activity.RESULT_CANCELED); + activity.finish(); + return; + } + PackageManager pm = activity.getPackageManager(); + pm.addOnPermissionsChangeListener(mPermissionChangeListener); + + // Get notified when the package is removed. + mPackageRemovalMonitor = new PackageRemovalMonitor(getContext(), packageName) { + @Override + public void onPackageRemoved() { + Log.w(LOG_TAG, packageName + " was uninstalled"); + activity.setResult(Activity.RESULT_CANCELED); + activity.finish(); + } + }; + mPackageRemovalMonitor.register(); + + // Check if the package was removed while this activity was not started. + try { + pm.getPackageInfo(packageName, 0); + } catch (NameNotFoundException e) { + Log.w(LOG_TAG, packageName + " was uninstalled while this activity was stopped", e); + activity.setResult(Activity.RESULT_CANCELED); + activity.finish(); + } + } + + @Override + public void onStop() { + super.onStop(); + + if (mPackageRemovalMonitor != null) { + mPackageRemovalMonitor.unregister(); + mPackageRemovalMonitor = null; + } + + if (mPermissionChangeListener != null) { + getActivity().getPackageManager().removeOnPermissionsChangeListener( + mPermissionChangeListener); + mPermissionChangeListener = null; + } + } + /** * Build a string representing the amount of time passed since the most recent permission usage * by this AppPermissionGroup. @@ -663,4 +739,24 @@ public class AppPermissionFragment extends PermissionsFrameFragment { return b.create(); } } + + /** + * A listener for permission changes. + */ + private class PermissionChangeListener implements PackageManager.OnPermissionsChangedListener { + private final int mUid; + + PermissionChangeListener(int uid) throws NameNotFoundException { + mUid = uid; + } + + @Override + public void onPermissionsChanged(int uid) { + if (uid == mUid) { + Log.w(LOG_TAG, "Permissions changed."); + createAppPermissionGroup(); + updateButtons(); + } + } + } } diff --git a/src/com/android/packageinstaller/permission/utils/PackageRemovalMonitor.java b/src/com/android/packageinstaller/permission/utils/PackageRemovalMonitor.java index ec6c5dafa..28413d194 100644 --- a/src/com/android/packageinstaller/permission/utils/PackageRemovalMonitor.java +++ b/src/com/android/packageinstaller/permission/utils/PackageRemovalMonitor.java @@ -51,6 +51,7 @@ public abstract class PackageRemovalMonitor extends BroadcastReceiver { public void register() { IntentFilter packageRemovedFilter = new IntentFilter(); packageRemovedFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); + packageRemovedFilter.addDataScheme("package"); mContext.registerReceiver(this, packageRemovedFilter); } -- GitLab From bea209bc690bf00edbbfe7809d173a245ebf611b Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Fri, 16 Nov 2018 14:25:16 -0800 Subject: [PATCH 141/701] Show system-fixed permissions but do not allow them to be disabled. Instead of not showing system-fixed permissions as we did before, we now show them. The controls are disabled so users cannot disabled them, and we show a short message explaining this. Bug: 119622068 Test: See disabled toggles for system-fixed permissions in AppPermissionFragment, AppPermissionsFragment, and PermissionAppsFragment. Change-Id: I6805ba7bf4736c2c7561ffdbd30178d1a4243b45 --- res/values/strings.xml | 3 ++ .../ui/handheld/AppPermissionFragment.java | 30 ++++++++++++------- .../ui/handheld/PermissionPreference.java | 17 +++++++++-- .../ui/television/AppPermissionsFragment.java | 8 +++-- .../ui/television/PermissionAppsFragment.java | 15 ++++++---- .../ui/wear/AppPermissionsFragmentWear.java | 2 +- .../wear/ReviewPermissionsWearFragment.java | 4 +-- .../permission/utils/Utils.java | 16 ---------- 8 files changed, 56 insertions(+), 39 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 20cf27d5b..6064750ba 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -158,6 +158,9 @@ Foreground access enabled by admin + + Permission set by system + @string/permission_access_always @string/permission_access_only_foreground diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java index a903f3bed..4cef4673b 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java @@ -220,23 +220,20 @@ public class AppPermissionFragment extends PermissionsFrameFragment { // Handle the UI for various special cases. Context context = getContext(); - if (isPolicyFullyFixed() || isForegroundDisabledByPolicy()) { + if (isSystemFixed() || isPolicyFullyFixed() || isForegroundDisabledByPolicy()) { // Disable changing permissions and potentially show administrator message. + mAlwaysButton.setEnabled(false); + mForegroundOnlyButton.setEnabled(false); + mDenyButton.setEnabled(false); + EnforcedAdmin admin = getAdmin(); if (admin != null) { - mAlwaysButton.setEnabled(false); - mForegroundOnlyButton.setEnabled(false); - mDenyButton.setEnabled(false); - showRightIcon(R.drawable.ic_info); mWidgetFrame.setOnClickListener(v -> RestrictedLockUtils.sendShowAdminSupportDetailsIntent(context, admin) ); - } else { - mAlwaysButton.setEnabled(false); - mForegroundOnlyButton.setEnabled(false); - mDenyButton.setEnabled(false); } + updateDetailForFixedByPolicyPermissionGroup(); } else if (Utils.areGroupPermissionsIndividuallyControlled(context, mGroup.getName())) { // If the permissions are individually controlled, also show a link to the page that @@ -333,6 +330,15 @@ public class AppPermissionFragment extends PermissionsFrameFragment { } } + /** + * Are any permissions of this group fixed by the system, i.e. not changeable by the user. + * + * @return {@code true} iff any permission is fixed + */ + private boolean isSystemFixed() { + return mGroup.isSystemFixed(); + } + /** * Is any foreground permissions of this group fixed by the policy, i.e. not changeable by the * user. @@ -392,7 +398,11 @@ public class AppPermissionFragment extends PermissionsFrameFragment { boolean hasAdmin = admin != null; - if (isForegroundDisabledByPolicy()) { + if (isSystemFixed()) { + // Permission is fully controlled by the system and cannot be switched + + setDetail(R.string.permission_summary_enabled_system_fixed); + } else if (isForegroundDisabledByPolicy()) { // Permission is fully controlled by policy and cannot be switched if (hasAdmin) { diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionPreference.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionPreference.java index 45f797d9c..7c7ef86b1 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionPreference.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionPreference.java @@ -133,6 +133,15 @@ class PermissionPreference extends MultiTargetSwitchPreference { updateUi(); } + /** + * Are any permissions of this group fixed by the system, i.e. not changeable by the user. + * + * @return {@code true} iff any permission is fixed + */ + private boolean isSystemFixed() { + return mGroup.isSystemFixed(); + } + /** * Is any foreground permissions of this group fixed by the policy, i.e. not changeable by the * user. @@ -200,7 +209,7 @@ class PermissionPreference extends MultiTargetSwitchPreference { setChecked(mGroup.areRuntimePermissionsGranted()); - if (isPolicyFullyFixed() || isForegroundDisabledByPolicy()) { + if (isSystemFixed() || isPolicyFullyFixed() || isForegroundDisabledByPolicy()) { if (admin != null) { setWidgetLayoutResource(R.layout.restricted_icon); @@ -338,7 +347,11 @@ class PermissionPreference extends MultiTargetSwitchPreference { boolean hasAdmin = admin != null; - if (isForegroundDisabledByPolicy()) { + if (isSystemFixed()) { + // Permission is fully controlled by the system and cannot be switched + + setSummary(R.string.permission_summary_enabled_system_fixed); + } else if (isForegroundDisabledByPolicy()) { // Permission is fully controlled by policy and cannot be switched if (hasAdmin) { diff --git a/src/com/android/packageinstaller/permission/ui/television/AppPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/television/AppPermissionsFragment.java index 935d4ffeb..5b5961af6 100644 --- a/src/com/android/packageinstaller/permission/ui/television/AppPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/television/AppPermissionsFragment.java @@ -43,13 +43,13 @@ import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceViewHolder; import androidx.preference.SwitchPreference; -import com.android.permissioncontroller.R; import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.model.AppPermissions; import com.android.packageinstaller.permission.ui.ReviewPermissionsActivity; import com.android.packageinstaller.permission.utils.LocationUtils; import com.android.packageinstaller.permission.utils.SafetyNetLogger; import com.android.packageinstaller.permission.utils.Utils; +import com.android.permissioncontroller.R; public final class AppPermissionsFragment extends SettingsWithHeader implements OnPreferenceChangeListener { @@ -204,11 +204,13 @@ public final class AppPermissionsFragment extends SettingsWithHeader preference.setIcon(Utils.applyTint(getContext(), icon, android.R.attr.colorControlNormal)); preference.setTitle(group.getLabel()); - if (group.isPolicyFixed()) { + if (group.isSystemFixed()) { + preference.setSummary(getString(R.string.permission_summary_enabled_system_fixed)); + } else if (group.isPolicyFixed()) { preference.setSummary(getString(R.string.permission_summary_enforced_by_policy)); } preference.setPersistent(false); - preference.setEnabled(!group.isPolicyFixed()); + preference.setEnabled(!group.isSystemFixed() && !group.isPolicyFixed()); preference.setChecked(group.areRuntimePermissionsGranted()); if (isPlatform) { diff --git a/src/com/android/packageinstaller/permission/ui/television/PermissionAppsFragment.java b/src/com/android/packageinstaller/permission/ui/television/PermissionAppsFragment.java index 0ca2f7880..825394f36 100644 --- a/src/com/android/packageinstaller/permission/ui/television/PermissionAppsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/television/PermissionAppsFragment.java @@ -38,7 +38,6 @@ import androidx.preference.PreferenceScreen; import androidx.preference.SwitchPreference; import com.android.packageinstaller.DeviceUtils; -import com.android.permissioncontroller.R; import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.model.PermissionApps; import com.android.packageinstaller.permission.model.PermissionApps.Callback; @@ -47,6 +46,7 @@ import com.android.packageinstaller.permission.ui.ReviewPermissionsActivity; import com.android.packageinstaller.permission.utils.LocationUtils; import com.android.packageinstaller.permission.utils.SafetyNetLogger; import com.android.packageinstaller.permission.utils.Utils; +import com.android.permissioncontroller.R; public final class PermissionAppsFragment extends SettingsWithHeader implements Callback, OnPreferenceChangeListener { @@ -213,12 +213,15 @@ public final class PermissionAppsFragment extends SettingsWithHeader implements if (existingPref != null) { // If existing preference - only update its state. - if (app.isPolicyFixed()) { + if (app.isSystemFixed()) { + existingPref.setSummary(getString( + R.string.permission_summary_enabled_system_fixed)); + } else if (app.isPolicyFixed()) { existingPref.setSummary(getString( R.string.permission_summary_enforced_by_policy)); } existingPref.setPersistent(false); - existingPref.setEnabled(!app.isPolicyFixed()); + existingPref.setEnabled(!app.isSystemFixed() && !app.isPolicyFixed()); if (existingPref instanceof SwitchPreference) { ((SwitchPreference) existingPref) .setChecked(app.areRuntimePermissionsGranted()); @@ -231,11 +234,13 @@ public final class PermissionAppsFragment extends SettingsWithHeader implements pref.setKey(app.getKey()); pref.setIcon(app.getIcon()); pref.setTitle(app.getLabel()); - if (app.isPolicyFixed()) { + if (app.isSystemFixed()) { + pref.setSummary(getString(R.string.permission_summary_enabled_system_fixed)); + } else if (app.isPolicyFixed()) { pref.setSummary(getString(R.string.permission_summary_enforced_by_policy)); } pref.setPersistent(false); - pref.setEnabled(!app.isPolicyFixed()); + pref.setEnabled(!app.isSystemFixed() && !app.isPolicyFixed()); pref.setChecked(app.areRuntimePermissionsGranted()); if (isSystemApp && isTelevision) { diff --git a/src/com/android/packageinstaller/permission/ui/wear/AppPermissionsFragmentWear.java b/src/com/android/packageinstaller/permission/ui/wear/AppPermissionsFragmentWear.java index 20934bf96..0e65e33a2 100644 --- a/src/com/android/packageinstaller/permission/ui/wear/AppPermissionsFragmentWear.java +++ b/src/com/android/packageinstaller/permission/ui/wear/AppPermissionsFragmentWear.java @@ -322,7 +322,7 @@ public final class AppPermissionsFragmentWear extends PreferenceFragmentCompat { pref.setTitle(group.getLabel()); pref.setChecked(group.areRuntimePermissionsGranted()); - if (group.isPolicyFixed()) { + if (group.isSystemFixed() || group.isPolicyFixed()) { pref.setEnabled(false); } else { pref.setOnPreferenceChangeListener((p, newVal) -> { diff --git a/src/com/android/packageinstaller/permission/ui/wear/ReviewPermissionsWearFragment.java b/src/com/android/packageinstaller/permission/ui/wear/ReviewPermissionsWearFragment.java index 1ab4de68b..6397cd7c0 100644 --- a/src/com/android/packageinstaller/permission/ui/wear/ReviewPermissionsWearFragment.java +++ b/src/com/android/packageinstaller/permission/ui/wear/ReviewPermissionsWearFragment.java @@ -37,10 +37,10 @@ import androidx.preference.SwitchPreference; import androidx.preference.TwoStatePreference; import androidx.wear.ble.view.WearableDialogHelper; -import com.android.permissioncontroller.R; import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.model.AppPermissions; import com.android.packageinstaller.permission.utils.Utils; +import com.android.permissioncontroller.R; import java.util.List; @@ -159,7 +159,7 @@ public class ReviewPermissionsWearFragment extends PreferenceFragmentCompat preference.setChecked(group.areRuntimePermissionsGranted()); // Mutable state - if (group.isPolicyFixed()) { + if (group.isSystemFixed() || group.isPolicyFixed()) { preference.setEnabled(false); } else { preference.setEnabled(true); diff --git a/src/com/android/packageinstaller/permission/utils/Utils.java b/src/com/android/packageinstaller/permission/utils/Utils.java index 78a97784b..87f126f46 100644 --- a/src/com/android/packageinstaller/permission/utils/Utils.java +++ b/src/com/android/packageinstaller/permission/utils/Utils.java @@ -118,22 +118,6 @@ public final class Utils { * @return */ public static boolean shouldShowPermission(Context context, AppPermissionGroup group) { - boolean isSystemFixed = group.isSystemFixed(); - if (group.getBackgroundPermissions() != null) { - // If the foreground mode is fixed to "enabled", the background mode might still be - // switchable. We only want to suppress the group if nothing can be switched - if (group.areRuntimePermissionsGranted()) { - isSystemFixed &= group.getBackgroundPermissions().isSystemFixed(); - } - } - - // We currently will not show permissions fixed by the system. - // which is what the system does for system components. - if (isSystemFixed && !LocationUtils.isLocationGroupAndProvider(context, - group.getName(), group.getApp().packageName)) { - return false; - } - if (!group.isGrantingAllowed()) { return false; } -- GitLab From f148b42bada66cfbbecdc1592f7efdce95c5a11b Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Sun, 18 Nov 2018 17:52:27 -0700 Subject: [PATCH 142/701] Define roles for Gallery and Music apps. The new storage work in Q will extend capabilities to the default Gallery and default Music apps, and we'll be implementing the management of those default apps using the new roles feature. This change starts by defining these roles using a relaxed definition that only uses the existing CATEGORY_APP_* intent filters. Bug: 119713234 Test: manual Change-Id: Id6795cd9a8311e87b1b0b0a9482b6b322204233c --- res/values/strings.xml | 7 +++++-- res/xml/roles.xml | 30 ++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 20cf27d5b..82d67134e 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -333,10 +333,13 @@ Phone app - SMS app - Browser app + + Gallery app + + Music app + diff --git a/res/xml/roles.xml b/res/xml/roles.xml index 1530494e9..accda95d9 100644 --- a/res/xml/roles.xml +++ b/res/xml/roles.xml @@ -230,4 +230,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- GitLab From 1b12b90bcfd1842a1f6ca8e6a210a7046ddc2702 Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Mon, 19 Nov 2018 09:47:17 -0800 Subject: [PATCH 143/701] Remove PermissionGroupChange from presubmit The test devices are under heavy load and exhibit a very different runtime behavior. UI tests relying on many apps behaving more or less in sync continue to be very flaky on test devices. Test: None, only happens on automated test devices Change-Id: I1e7d204e11430ab3966ff1a06abdedfbbc8031e8 Fixes: 119741311 --- TEST_MAPPING | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/TEST_MAPPING b/TEST_MAPPING index 6f8a76eba..83f1155fd 100644 --- a/TEST_MAPPING +++ b/TEST_MAPPING @@ -5,11 +5,8 @@ "options": [ { "include-filter": "android.permission.cts.BackgroundPermissionsTest" - }, - { - "include-filter": "android.permission.cts.PermissionGroupChange" } ] } ] -} \ No newline at end of file +} -- GitLab From d59ba5786f29c4ac0ac827b8183fb472e3636475 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Mon, 19 Nov 2018 14:12:37 -0800 Subject: [PATCH 144/701] Fix back button in Permissions Hub screens. Bug: 119767086 Test: Used the back button in all three screens. Change-Id: I0a445f5fad050c7cd16c1613d1b30786399289f7 --- .../permission/ui/handheld/AppPermissionFragment.java | 10 ++++++++++ .../ui/handheld/AppPermissionUsageFragment.java | 10 ++++++++++ .../ui/handheld/PermissionUsageFragment.java | 2 +- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java index 505dc957e..d3d564b49 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java @@ -34,6 +34,7 @@ import android.os.Bundle; import android.os.UserHandle; import android.util.Log; import android.view.LayoutInflater; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; @@ -247,6 +248,15 @@ public class AppPermissionFragment extends PermissionsFrameFragment { } } + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + getActivity().finish(); + return true; + } + return super.onOptionsItemSelected(item); + } + /** * Build a string representing the amount of time passed since the most recent permission usage * by this AppPermissionGroup. diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java index 5f1e7c40c..10a4da1e6 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java @@ -29,6 +29,7 @@ import android.os.UserHandle; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Log; +import android.view.MenuItem; import android.view.View; import android.widget.Toast; @@ -117,6 +118,15 @@ public class AppPermissionUsageFragment extends SettingsWithHeader { } } + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + getActivity().finish(); + return true; + } + return super.onOptionsItemSelected(item); + } + private static PackageInfo getPackageInfo(@NonNull Activity activity, @NonNull String packageName) { try { diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java index 0c4ad8239..4b27b5571 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java @@ -211,7 +211,7 @@ public class PermissionUsageFragment extends PermissionsFrameFragment implements public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: - getFragmentManager().popBackStack(); + getActivity().finish(); return true; case MENU_SHOW_SYSTEM: case MENU_HIDE_SYSTEM: -- GitLab From 21f8fac69b9c2fe80c3e38bf613dbb25e085b5fb Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Fri, 16 Nov 2018 15:47:25 -0800 Subject: [PATCH 145/701] Fix role granting flow. This change fixes various issues related to the role granting flow, including adding the SET_PREFERRED_APPLICATIONS permission to permission controller for roles, fixing typo and permissions in roles.xml and fixing roles.xml parsing. Bug: 110557011 Test: build Change-Id: I7e4e855e8efcda83d58d29054218e7df044b430e --- AndroidManifest.xml | 1 + res/xml/roles.xml | 26 ++--- .../role/model/Permissions.java | 9 +- .../packageinstaller/role/model/Roles.java | 94 ++++++++++++------- .../role/ui/RequestRoleActivity.java | 2 +- .../role/ui/RequestRoleFragment.java | 14 ++- .../role/ui/RequestRoleLiveData.java | 3 +- 7 files changed, 90 insertions(+), 59 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 98b31ead4..3c1be8248 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -25,6 +25,7 @@ + diff --git a/res/xml/roles.xml b/res/xml/roles.xml index 1530494e9..325f33eaf 100644 --- a/res/xml/roles.xml +++ b/res/xml/roles.xml @@ -68,31 +68,31 @@ + + - - - + + - - + } --> + - - + } --> @@ -117,7 +117,7 @@ - + @@ -129,7 +129,7 @@ - + @@ -187,7 +187,7 @@ - + @@ -210,7 +210,7 @@ - + diff --git a/src/com/android/packageinstaller/role/model/Permissions.java b/src/com/android/packageinstaller/role/model/Permissions.java index a5906fa3b..d4ca5371b 100644 --- a/src/com/android/packageinstaller/role/model/Permissions.java +++ b/src/com/android/packageinstaller/role/model/Permissions.java @@ -24,6 +24,7 @@ import android.content.pm.PackageManager; import android.content.pm.PermissionGroupInfo; import android.content.pm.PermissionInfo; import android.os.Build; +import android.os.Process; import android.os.UserHandle; import android.permission.PermissionManager; import android.util.ArrayMap; @@ -506,7 +507,7 @@ public class Permissions { private static int getPermissionFlags(@NonNull String packageName, @NonNull String permission, @NonNull Context context) { PackageManager packageManager = context.getPackageManager(); - UserHandle user = UserHandle.of(UserHandle.myUserId()); + UserHandle user = Process.myUserHandle(); return packageManager.getPermissionFlags(permission, packageName, user); } @@ -534,7 +535,7 @@ public class Permissions { private static void setPermissionFlags(@NonNull String packageName, @NonNull String permission, int flags, int mask, @NonNull Context context) { PackageManager packageManager = context.getPackageManager(); - UserHandle user = UserHandle.of(UserHandle.myUserId()); + UserHandle user = Process.myUserHandle(); packageManager.updatePermissionFlags(permission, packageName, mask, flags, user); } @@ -555,7 +556,7 @@ public class Permissions { return false; } PackageManager packageManager = context.getPackageManager(); - UserHandle user = UserHandle.of(UserHandle.myUserId()); + UserHandle user = Process.myUserHandle(); packageManager.grantRuntimePermission(packageName, permission, user); return true; } @@ -566,7 +567,7 @@ public class Permissions { return false; } PackageManager packageManager = context.getPackageManager(); - UserHandle user = UserHandle.of(UserHandle.myUserId()); + UserHandle user = Process.myUserHandle(); packageManager.revokeRuntimePermission(packageName, permission, user); return true; } diff --git a/src/com/android/packageinstaller/role/model/Roles.java b/src/com/android/packageinstaller/role/model/Roles.java index 0f319f9ba..fecb81e13 100644 --- a/src/com/android/packageinstaller/role/model/Roles.java +++ b/src/com/android/packageinstaller/role/model/Roles.java @@ -67,7 +67,7 @@ public class Roles { private static final String TAG_PERMISSIONS = "permissions"; private static final String TAG_APP_OPS = "app-ops"; private static final String TAG_APP_OP = "app-op"; - private static final String TAG_PREFERRED_ACTIVITIES = "preferred-activites"; + private static final String TAG_PREFERRED_ACTIVITIES = "preferred-activities"; private static final String TAG_PREFERRED_ACTIVITY = "preferred-activity"; private static final String ATTRIBUTE_NAME = "name"; private static final String ATTRIBUTE_PERMISSION = "permission"; @@ -139,11 +139,13 @@ public class Roles { @NonNull XmlResourceParser parser) throws IOException, XmlPullParserException { Pair, Map> xml = null; - int outerDepth = parser.getDepth(); int type; + int depth; + int innerDepth = parser.getDepth() + 1; while ((type = parser.next()) != XmlResourceParser.END_DOCUMENT - && (type != XmlResourceParser.END_TAG || parser.getDepth() > outerDepth)) { - if (type == XmlResourceParser.END_TAG || type == XmlResourceParser.TEXT) { + && ((depth = parser.getDepth()) >= innerDepth + || type != XmlResourceParser.END_TAG)) { + if (depth > innerDepth || type != XmlResourceParser.START_TAG) { continue; } @@ -172,11 +174,13 @@ public class Roles { Map permissionSets = new ArrayMap<>(); Map roles = new ArrayMap<>(); - int outerDepth = parser.getDepth(); int type; + int depth; + int innerDepth = parser.getDepth() + 1; while ((type = parser.next()) != XmlResourceParser.END_DOCUMENT - && (type != XmlResourceParser.END_TAG || parser.getDepth() > outerDepth)) { - if (type == XmlResourceParser.END_TAG || type == XmlResourceParser.TEXT) { + && ((depth = parser.getDepth()) >= innerDepth + || type != XmlResourceParser.END_TAG)) { + if (depth > innerDepth || type != XmlResourceParser.START_TAG) { continue; } @@ -220,11 +224,13 @@ public class Roles { List permissions = new ArrayList<>(); - int outerDepth = parser.getDepth(); int type; + int depth; + int innerDepth = parser.getDepth() + 1; while ((type = parser.next()) != XmlResourceParser.END_DOCUMENT - && (type != XmlResourceParser.END_TAG || parser.getDepth() > outerDepth)) { - if (type == XmlResourceParser.END_TAG || type == XmlResourceParser.TEXT) { + && ((depth = parser.getDepth()) >= innerDepth + || type != XmlResourceParser.END_TAG)) { + if (depth > innerDepth || type != XmlResourceParser.START_TAG) { continue; } @@ -272,11 +278,13 @@ public class Roles { List appOps = null; List preferredActivities = null; - int outerDepth = parser.getDepth(); int type; + int depth; + int innerDepth = parser.getDepth() + 1; while ((type = parser.next()) != XmlResourceParser.END_DOCUMENT - && (type != XmlResourceParser.END_TAG || parser.getDepth() > outerDepth)) { - if (type == XmlResourceParser.END_TAG || type == XmlResourceParser.TEXT) { + && ((depth = parser.getDepth()) >= innerDepth + || type != XmlResourceParser.END_TAG)) { + if (depth > innerDepth || type != XmlResourceParser.START_TAG) { continue; } @@ -340,11 +348,13 @@ public class Roles { @NonNull XmlResourceParser parser) throws IOException, XmlPullParserException { List requiredComponents = new ArrayList<>(); - int outerDepth = parser.getDepth(); int type; + int depth; + int innerDepth = parser.getDepth() + 1; while ((type = parser.next()) != XmlResourceParser.END_DOCUMENT - && (type != XmlResourceParser.END_TAG || parser.getDepth() > outerDepth)) { - if (type == XmlResourceParser.END_TAG || type == XmlResourceParser.TEXT) { + && ((depth = parser.getDepth()) >= innerDepth + || type != XmlResourceParser.END_TAG)) { + if (depth > innerDepth || type != XmlResourceParser.START_TAG) { continue; } @@ -379,11 +389,13 @@ public class Roles { IntentFilterData intentFilterData = null; ArrayMap metaData = new ArrayMap<>(); - int outerDepth = parser.getDepth(); int type; + int depth; + int innerDepth = parser.getDepth() + 1; while ((type = parser.next()) != XmlResourceParser.END_DOCUMENT - && (type != XmlResourceParser.END_TAG || parser.getDepth() > outerDepth)) { - if (type == XmlResourceParser.END_TAG || type == XmlResourceParser.TEXT) { + && ((depth = parser.getDepth()) >= innerDepth + || type != XmlResourceParser.END_TAG)) { + if (depth > innerDepth || type != XmlResourceParser.START_TAG) { continue; } @@ -447,11 +459,13 @@ public class Roles { String dataScheme = null; String dataType = null; - int outerDepth = parser.getDepth(); int type; + int depth; + int innerDepth = parser.getDepth() + 1; while ((type = parser.next()) != XmlResourceParser.END_DOCUMENT - && (type != XmlResourceParser.END_TAG || parser.getDepth() > outerDepth)) { - if (type == XmlResourceParser.END_TAG || type == XmlResourceParser.TEXT) { + && ((depth = parser.getDepth()) >= innerDepth + || type != XmlResourceParser.END_TAG)) { + if (depth > innerDepth || type != XmlResourceParser.START_TAG) { continue; } @@ -525,11 +539,13 @@ public class Roles { XmlPullParserException { List permissions = new ArrayList<>(); - int outerDepth = parser.getDepth(); int type; + int depth; + int innerDepth = parser.getDepth() + 1; while ((type = parser.next()) != XmlResourceParser.END_DOCUMENT - && (type != XmlResourceParser.END_TAG || parser.getDepth() > outerDepth)) { - if (type == XmlResourceParser.END_TAG || type == XmlResourceParser.TEXT) { + && ((depth = parser.getDepth()) >= innerDepth + || type != XmlResourceParser.END_TAG)) { + if (depth > innerDepth || type != XmlResourceParser.START_TAG) { continue; } @@ -574,11 +590,13 @@ public class Roles { List appOpNames = new ArrayList<>(); List appOps = new ArrayList<>(); - int outerDepth = parser.getDepth(); int type; + int depth; + int innerDepth = parser.getDepth() + 1; while ((type = parser.next()) != XmlResourceParser.END_DOCUMENT - && (type != XmlResourceParser.END_TAG || parser.getDepth() > outerDepth)) { - if (type == XmlResourceParser.END_TAG || type == XmlResourceParser.TEXT) { + && ((depth = parser.getDepth()) >= innerDepth + || type != XmlResourceParser.END_TAG)) { + if (depth > innerDepth || type != XmlResourceParser.START_TAG) { continue; } @@ -623,11 +641,13 @@ public class Roles { @NonNull XmlResourceParser parser) throws IOException, XmlPullParserException { List preferredActivities = new ArrayList<>(); - int outerDepth = parser.getDepth(); int type; + int depth; + int innerDepth = parser.getDepth() + 1; while ((type = parser.next()) != XmlResourceParser.END_DOCUMENT - && (type != XmlResourceParser.END_TAG || parser.getDepth() > outerDepth)) { - if (type == XmlResourceParser.END_TAG || type == XmlResourceParser.TEXT) { + && ((depth = parser.getDepth()) >= innerDepth + || type != XmlResourceParser.END_TAG)) { + if (depth > innerDepth || type != XmlResourceParser.START_TAG) { continue; } @@ -654,11 +674,13 @@ public class Roles { RequiredActivity activity = null; List intentFilterDatas = new ArrayList<>(); - int outerDepth = parser.getDepth(); int type; + int depth; + int innerDepth = parser.getDepth() + 1; while ((type = parser.next()) != XmlResourceParser.END_DOCUMENT - && (type != XmlResourceParser.END_TAG || parser.getDepth() > outerDepth)) { - if (type == XmlResourceParser.END_TAG || type == XmlResourceParser.TEXT) { + && ((depth = parser.getDepth()) >= innerDepth + || type != XmlResourceParser.END_TAG)) { + if (depth > innerDepth || type != XmlResourceParser.START_TAG) { continue; } @@ -699,10 +721,10 @@ public class Roles { private static void skipCurrentTag(@NonNull XmlResourceParser parser) throws XmlPullParserException, IOException { - int outerDepth = parser.getDepth(); int type; + int innerDepth = parser.getDepth() + 1; while ((type = parser.next()) != XmlResourceParser.END_DOCUMENT - && (type != XmlResourceParser.END_TAG || parser.getDepth() > outerDepth)) { + && (parser.getDepth() >= innerDepth || type != XmlResourceParser.END_TAG)) { // Do nothing } } diff --git a/src/com/android/packageinstaller/role/ui/RequestRoleActivity.java b/src/com/android/packageinstaller/role/ui/RequestRoleActivity.java index e739f14db..040040130 100644 --- a/src/com/android/packageinstaller/role/ui/RequestRoleActivity.java +++ b/src/com/android/packageinstaller/role/ui/RequestRoleActivity.java @@ -96,7 +96,7 @@ public class RequestRoleActivity extends FragmentActivity { RequestRoleFragment fragment = RequestRoleFragment.newInstance( roleName, packageName); getSupportFragmentManager().beginTransaction() - .replace(android.R.id.content, fragment) + .add(fragment, null) .commit(); } } diff --git a/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java b/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java index 486f4d1d9..dc9e42846 100644 --- a/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java +++ b/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java @@ -17,6 +17,7 @@ package com.android.packageinstaller.role.ui; import android.app.Activity; +import android.app.AlertDialog; import android.app.Dialog; import android.app.role.RoleManager; import android.content.Context; @@ -28,7 +29,6 @@ import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.DialogFragment; import androidx.lifecycle.ViewModelProviders; @@ -122,11 +122,17 @@ public class RequestRoleFragment extends DialogFragment { } CharSequence message = Html.fromHtml(messageHtml, Html.FROM_HTML_MODE_LEGACY); - return new AlertDialog.Builder(context, getTheme()) + // Set the button listeners later to get rid of the automatic dismiss behavior. + AlertDialog dialog = new AlertDialog.Builder(context, getTheme()) .setMessage(message) - .setPositiveButton(android.R.string.ok, (dialog, which) -> addRoleHolder()) - .setNegativeButton(android.R.string.cancel, (dialog, which) -> finish()) + .setPositiveButton(android.R.string.ok, null) + .setNegativeButton(android.R.string.cancel, null) .create(); + dialog.setOnShowListener(dialog2 -> { + dialog.getButton(Dialog.BUTTON_POSITIVE).setOnClickListener(view -> addRoleHolder()); + dialog.getButton(Dialog.BUTTON_NEGATIVE).setOnClickListener(view -> finish()); + }); + return dialog; } @Override diff --git a/src/com/android/packageinstaller/role/ui/RequestRoleLiveData.java b/src/com/android/packageinstaller/role/ui/RequestRoleLiveData.java index 42c0b472c..564a064af 100644 --- a/src/com/android/packageinstaller/role/ui/RequestRoleLiveData.java +++ b/src/com/android/packageinstaller/role/ui/RequestRoleLiveData.java @@ -19,6 +19,7 @@ package com.android.packageinstaller.role.ui; import android.app.role.RoleManager; import android.app.role.RoleManagerCallback; import android.content.Context; +import android.os.Process; import android.os.UserHandle; import android.util.Log; @@ -63,7 +64,7 @@ public class RequestRoleLiveData extends LiveData { setValue(STATE_ADDING); RoleManager roleManager = context.getSystemService(RoleManager.class); - UserHandle user = UserHandle.of(UserHandle.myUserId()); + UserHandle user = Process.myUserHandle(); Executor executor = context.getMainExecutor(); roleManager.addRoleHolderAsUser(roleName, packageName, user, executor, new RoleManagerCallback() { -- GitLab From 4653b483a709f5481e16fa08b1c16922f6104743 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Tue, 20 Nov 2018 08:13:58 -0800 Subject: [PATCH 146/701] Prevent spinner overlaps with large font size. This stops the two spinners in PermissionUsageFragment from overlapping when the font or display sizes are set to large. Using ButtonBarLayout allows them to switch to being stacked vertically when there is not enough space for them horizontally. This slightly modified the behavior of ButtonBarLayout to prevent them from being right-aligned when stacked vertically. Bug: 119771291 Test: Set font and display size to large and see no overlap. Change-Id: I8ae9bc9cdb49d728aaa09d5238ba31df36c62997 --- res/layout/permission_usage_filter_spinners.xml | 10 ++++++++-- .../permission/ui/ButtonBarLayout.java | 4 +++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/res/layout/permission_usage_filter_spinners.xml b/res/layout/permission_usage_filter_spinners.xml index 9de70052e..c63bd89c2 100644 --- a/res/layout/permission_usage_filter_spinners.xml +++ b/res/layout/permission_usage_filter_spinners.xml @@ -15,7 +15,7 @@ limitations under the License. --> - + + - + diff --git a/src/com/android/packageinstaller/permission/ui/ButtonBarLayout.java b/src/com/android/packageinstaller/permission/ui/ButtonBarLayout.java index 061c85a80..12a4bbd69 100644 --- a/src/com/android/packageinstaller/permission/ui/ButtonBarLayout.java +++ b/src/com/android/packageinstaller/permission/ui/ButtonBarLayout.java @@ -97,7 +97,9 @@ public class ButtonBarLayout extends LinearLayout { private void setStacked(boolean stacked) { setOrientation(stacked ? LinearLayout.VERTICAL : LinearLayout.HORIZONTAL); - setGravity(stacked ? Gravity.END : Gravity.BOTTOM); + if (getGravity() != Gravity.CENTER) { + setGravity(stacked ? Gravity.END : Gravity.BOTTOM); + } final View spacer = findViewById(R.id.spacer); if (spacer != null) { -- GitLab From 6368ed96b7c8cf5713a95b2abbe6bf52e112ade5 Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Tue, 20 Nov 2018 11:24:16 -0800 Subject: [PATCH 147/701] Add role initialization to RoleControllerService. This change uses RoleManager.setRoleNamesFromController() to initialize the roles for a user. Bug: 110557011 Test: build Change-Id: I2e2553f3ef988261bac6817a53974c79d2788320 --- AndroidManifest.xml | 4 +- .../packageinstaller/role/model/Roles.java | 96 +++++++++++++------ .../service/RoleControllerServiceImpl.java | 7 ++ 3 files changed, 76 insertions(+), 31 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 3c1be8248..7c52c51f0 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -5,7 +5,7 @@ - @@ -26,7 +26,7 @@ - + diff --git a/src/com/android/packageinstaller/role/model/Roles.java b/src/com/android/packageinstaller/role/model/Roles.java index fecb81e13..eef7bb77f 100644 --- a/src/com/android/packageinstaller/role/model/Roles.java +++ b/src/com/android/packageinstaller/role/model/Roles.java @@ -37,7 +37,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; -import java.util.Map; import java.util.Objects; /** @@ -96,7 +95,7 @@ public class Roles { private static final Object sLock = new Object(); @Nullable - private static Map sRoles; + private static ArrayMap sRoles; private Roles() {} @@ -108,7 +107,7 @@ public class Roles { * @return a map from role name to {@link Role} instances */ @NonNull - public static Map getRoles(@NonNull Context context) { + public static ArrayMap getRoles(@NonNull Context context) { synchronized (sLock) { if (sRoles == null) { sRoles = loadRoles(context); @@ -118,26 +117,26 @@ public class Roles { } @NonNull - private static Map loadRoles(@NonNull Context context) { + private static ArrayMap loadRoles(@NonNull Context context) { try (XmlResourceParser parser = context.getResources().getXml(R.xml.roles)) { - Pair, Map> xml = parseXml(parser); + Pair, ArrayMap> xml = parseXml(parser); if (xml == null) { - return Collections.emptyMap(); + return new ArrayMap<>(); } - Map permissionSets = xml.first; - Map roles = xml.second; + ArrayMap permissionSets = xml.first; + ArrayMap roles = xml.second; validateParseResult(permissionSets, roles, context); return roles; } catch (XmlPullParserException | IOException e) { throwOrLogMessage("Unable to parse roles.xml", e); - return Collections.emptyMap(); + return new ArrayMap<>(); } } @Nullable - private static Pair, Map> parseXml( + private static Pair, ArrayMap> parseXml( @NonNull XmlResourceParser parser) throws IOException, XmlPullParserException { - Pair, Map> xml = null; + Pair, ArrayMap> xml = null; int type; int depth; @@ -169,10 +168,10 @@ public class Roles { } @NonNull - private static Pair, Map> parseRoles( + private static Pair, ArrayMap> parseRoles( @NonNull XmlResourceParser parser) throws IOException, XmlPullParserException { - Map permissionSets = new ArrayMap<>(); - Map roles = new ArrayMap<>(); + ArrayMap permissionSets = new ArrayMap<>(); + ArrayMap roles = new ArrayMap<>(); int type; int depth; @@ -252,7 +251,7 @@ public class Roles { @Nullable private static Role parseRole(@NonNull XmlResourceParser parser, - @NonNull Map permissionSets) throws IOException, + @NonNull ArrayMap permissionSets) throws IOException, XmlPullParserException { String name = requireAttributeValue(parser, ATTRIBUTE_NAME, TAG_ROLE); if (name == null) { @@ -535,7 +534,7 @@ public class Roles { @NonNull private static List parsePermissions(@NonNull XmlResourceParser parser, - @NonNull Map permissionSets) throws IOException, + @NonNull ArrayMap permissionSets) throws IOException, XmlPullParserException { List permissions = new ArrayList<>(); @@ -809,38 +808,77 @@ public class Roles { * a permission in {@code AppOpsManager} have declared that permission in its role and ensures * that all preferred activities are listed in the required components. */ - private static void validateParseResult(@NonNull Map permissionSets, - @NonNull Map roles, @NonNull Context context) { + private static void validateParseResult(@NonNull ArrayMap permissionSets, + @NonNull ArrayMap roles, @NonNull Context context) { if (!DEBUG) { return; } - for (PermissionSet permissionSet : permissionSets.values()) { - permissionSet.getPermissions().forEach(permission -> validatePermission(permission, - context)); + int permissionSetsSize = permissionSets.size(); + for (int permissionSetsIndex = 0; permissionSetsIndex < permissionSetsSize; + permissionSetsIndex++) { + PermissionSet permissionSet = permissionSets.valueAt(permissionSetsIndex); + + List permissions = permissionSet.getPermissions(); + int permissionsSize = permissions.size(); + for (int permissionsIndex = 0; permissionsIndex < permissionsSize; permissionsIndex++) { + String permission = permissions.get(permissionsIndex); + + validatePermission(permission, context); + } } - for (Role role : roles.values()) { - role.getRequiredComponents().forEach(requiredComponent -> { + + int rolesSize = roles.size(); + for (int rolesIndex = 0; rolesIndex < rolesSize; rolesIndex++) { + Role role = roles.valueAt(rolesIndex); + + List requiredComponents = role.getRequiredComponents(); + int requiredComponentsSize = requiredComponents.size(); + for (int requiredComponentsIndex = 0; requiredComponentsIndex < requiredComponentsSize; + requiredComponentsIndex++) { + RequiredComponent requiredComponent = requiredComponents.get( + requiredComponentsIndex); + String permission = requiredComponent.getPermission(); if (permission != null) { validatePermission(permission, context); } - }); - role.getPermissions().forEach(permission -> validatePermission(permission, context)); - role.getAppOps().forEach(appOp -> { + } + + List permissions = role.getPermissions(); + int permissionsSize = permissions.size(); + for (int i = 0; i < permissionsSize; i++) { + String permission = permissions.get(i); + + validatePermission(permission, context); + } + + List appOps = role.getAppOps(); + int appOpsSize = appOps.size(); + for (int i = 0; i < appOpsSize; i++) { + AppOp appOp = appOps.get(i); + String permission = AppOpsManager.opToPermission(appOp.getName()); if (permission != null) { throw new IllegalArgumentException("App op has an associated permission: " + appOp.getName()); } - }); - role.getPreferredActivities().forEach(preferredActivity -> { + } + + List preferredActivities = role.getPreferredActivities(); + int preferredActivitiesSize = preferredActivities.size(); + for (int preferredActivitiesIndex = 0; + preferredActivitiesIndex < preferredActivitiesSize; + preferredActivitiesIndex++) { + PreferredActivity preferredActivity = preferredActivities.get( + preferredActivitiesIndex); + if (!role.getRequiredComponents().contains(preferredActivity.getActivity())) { throw new IllegalArgumentException(" of not" + " required in , role: " + role.getName() + ", preferred activity: " + preferredActivity); } - }); + } } } diff --git a/src/com/android/packageinstaller/role/service/RoleControllerServiceImpl.java b/src/com/android/packageinstaller/role/service/RoleControllerServiceImpl.java index 8f879e0d4..b4a2c394a 100644 --- a/src/com/android/packageinstaller/role/service/RoleControllerServiceImpl.java +++ b/src/com/android/packageinstaller/role/service/RoleControllerServiceImpl.java @@ -24,6 +24,7 @@ import android.os.HandlerThread; import android.os.UserHandle; import android.rolecontrollerservice.RoleControllerService; import android.text.TextUtils; +import android.util.ArrayMap; import android.util.Log; import androidx.annotation.NonNull; @@ -33,6 +34,7 @@ import com.android.packageinstaller.role.model.Role; import com.android.packageinstaller.role.model.Roles; import com.android.packageinstaller.role.utils.PackageUtils; +import java.util.ArrayList; import java.util.List; /** @@ -122,6 +124,10 @@ public class RoleControllerServiceImpl extends RoleControllerService { @Override public void onGrantDefaultRoles(@NonNull RoleManagerCallback callback) { + ArrayMap roles = Roles.getRoles(this); + // TODO: Clean up holders of roles that will be removed. + List roleNames = new ArrayList<>(roles.keySet()); + mRoleManager.setRoleNamesFromController(roleNames); //TODO grant default permissions and appops Log.i(LOG_TAG, "Granting defaults for user " + UserHandle.myUserId()); callback.onSuccess(); @@ -162,6 +168,7 @@ public class RoleControllerServiceImpl extends RoleControllerService { int currentPackageNamesSize = currentPackageNames.size(); for (int i = 0; i < currentPackageNamesSize; i++) { String currentPackageName = currentPackageNames.get(i); + boolean removed = removeRoleHolderInternal(role, currentPackageName); if (!removed) { Log.e(LOG_TAG, "Failed to remove current holder from role holders in" -- GitLab From aed9cff4cf6d41dfe1f9a9542aa9624690e8ed3b Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Wed, 21 Nov 2018 11:04:20 -0800 Subject: [PATCH 148/701] Fix missing permission set in roles.xml This change fixes roles parser complaining about missing permission sets by commenting out only the permissions instead of the whole permission set. Bug: 110557011 Test: build Change-Id: Ibd030c4f38b3f8f7b0d7a80ca5acc9a44028a0b0 --- res/xml/roles.xml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/res/xml/roles.xml b/res/xml/roles.xml index 4101da1b2..d3626f6bd 100644 --- a/res/xml/roles.xml +++ b/res/xml/roles.xml @@ -76,23 +76,23 @@ - + + + + - } --> - + + + + + + - } --> -- GitLab From db01fd7d4d79fd461ab552810f55b15970a4b834 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Wed, 21 Nov 2018 10:37:43 -0800 Subject: [PATCH 149/701] Fix Permissions Hub handling of work profile. If users had the same app installed in the normal and the work profiles, PermissionUsageFragment previously only showed one of them (whichever was accessed more recently). I modified it to differentiate between different uids. In addition, AppPermissionFragment only worked on non-work profile apps. I modified it so that it can take in the users and uses that to get the correct app. Bug: 119811056 Test: Setup work profile, use both Contacts apps, give them different permissions, then see separate entries in PermissionUsageFragment and verify that AppPermissionFragment can change either app's permissions. Change-Id: I448c26850069ce539cb1afa82f72807da779da84 --- .../permission/model/AppPermissionGroup.java | 18 +++++++++++++++++- .../ui/ManagePermissionsActivity.java | 9 ++++++++- .../ui/handheld/AppPermissionFragment.java | 18 +++++++++++------- .../ui/handheld/PermissionUsageFragment.java | 3 ++- .../ui/handheld/PermissionUsagePreference.java | 2 ++ 5 files changed, 40 insertions(+), 10 deletions(-) diff --git a/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java b/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java index 8ac6123d9..147cdf415 100644 --- a/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java +++ b/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java @@ -109,6 +109,22 @@ public final class AppPermissionGroup implements Comparable public static AppPermissionGroup create(Context context, PackageInfo packageInfo, String permissionName, boolean delayChanges) { + return create(context, packageInfo, permissionName, Process.myUserHandle(), delayChanges); + } + + /** + * Create the app permission group. + * + * @param context the {@code Context} to retrieve system services. + * @param packageInfo package information about the app. + * @param permissionName the name of the permission this object represents. + * @param userHandle the user who owns the app. + * @param delayChanges whether to delay changes until {@link #persistChanges} is called. + * + * @return the AppPermissionGroup. + */ + public static AppPermissionGroup create(Context context, PackageInfo packageInfo, + String permissionName, UserHandle userHandle, boolean delayChanges) { PermissionInfo permissionInfo; try { permissionInfo = context.getPackageManager().getPermissionInfo(permissionName, 0); @@ -144,7 +160,7 @@ public final class AppPermissionGroup implements Comparable } return create(context, packageInfo, groupInfo, permissionInfos, - Process.myUserHandle(), delayChanges); + userHandle, delayChanges); } public static AppPermissionGroup create(Context context, PackageInfo packageInfo, diff --git a/src/com/android/packageinstaller/permission/ui/ManagePermissionsActivity.java b/src/com/android/packageinstaller/permission/ui/ManagePermissionsActivity.java index 0dc680ecf..101cfbbbd 100644 --- a/src/com/android/packageinstaller/permission/ui/ManagePermissionsActivity.java +++ b/src/com/android/packageinstaller/permission/ui/ManagePermissionsActivity.java @@ -23,6 +23,7 @@ import static com.android.packageinstaller.permission.service.PermissionSearchIn import android.content.Intent; import android.os.Bundle; +import android.os.UserHandle; import android.util.Log; import android.view.MenuItem; @@ -144,8 +145,14 @@ public final class ManagePermissionsActivity extends FragmentActivity { finish(); return; } + UserHandle userHandle = getIntent().getParcelableExtra(Intent.EXTRA_USER); + if (userHandle == null) { + Log.i(LOG_TAG, "Missing mandatory argument EXTRA_USER"); + finish(); + return; + } androidXFragment = com.android.packageinstaller.permission.ui.handheld - .AppPermissionFragment.newInstance(packageName, permissionName); + .AppPermissionFragment.newInstance(packageName, permissionName, userHandle); } break; default: { diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java index 505dc957e..5615bcd0e 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java @@ -103,11 +103,12 @@ public class AppPermissionFragment extends PermissionsFrameFragment { * @return A new fragment */ public static @NonNull AppPermissionFragment newInstance(@NonNull String packageName, - @NonNull String permissionName) { + @NonNull String permissionName, @NonNull UserHandle userHandle) { AppPermissionFragment fragment = new AppPermissionFragment(); Bundle arguments = new Bundle(); arguments.putString(Intent.EXTRA_PACKAGE_NAME, packageName); arguments.putString(Intent.EXTRA_PERMISSION_NAME, permissionName); + arguments.putParcelable(Intent.EXTRA_USER, userHandle); fragment.setArguments(arguments); return fragment; } @@ -132,10 +133,12 @@ public class AppPermissionFragment extends PermissionsFrameFragment { private void createAppPermissionGroup() { String packageName = getArguments().getString(Intent.EXTRA_PACKAGE_NAME); + UserHandle userHandle = getArguments().getParcelable(Intent.EXTRA_USER); Activity activity = getActivity(); Context context = getPreferenceManager().getContext(); - mGroup = AppPermissionGroup.create(context, getPackageInfo(activity, packageName), - getArguments().getString(Intent.EXTRA_PERMISSION_NAME), false); + mGroup = AppPermissionGroup.create(context, + getPackageInfo(activity, packageName, userHandle), + getArguments().getString(Intent.EXTRA_PERMISSION_NAME), userHandle, false); if (mGroup == null || !Utils.shouldShowPermission(context, mGroup)) { Log.i(LOG_TAG, "Illegal group: " + (mGroup == null ? "null" : mGroup.getName())); @@ -196,6 +199,7 @@ public class AppPermissionFragment extends PermissionsFrameFragment { super.onStart(); String packageName = getArguments().getString(Intent.EXTRA_PACKAGE_NAME); + UserHandle userHandle = getArguments().getParcelable(Intent.EXTRA_USER); Activity activity = getActivity(); // Get notified when permissions change. @@ -223,7 +227,7 @@ public class AppPermissionFragment extends PermissionsFrameFragment { // Check if the package was removed while this activity was not started. try { - pm.getPackageInfo(packageName, 0); + pm.getPackageInfoAsUser(packageName, 0, userHandle); } catch (NameNotFoundException e) { Log.w(LOG_TAG, packageName + " was uninstalled while this activity was stopped", e); activity.setResult(Activity.RESULT_CANCELED); @@ -394,10 +398,10 @@ public class AppPermissionFragment extends PermissionsFrameFragment { } private static @Nullable PackageInfo getPackageInfo(@NonNull Activity activity, - @NonNull String packageName) { + @NonNull String packageName, @NonNull UserHandle userHandle) { try { - return activity.getPackageManager().getPackageInfo( - packageName, PackageManager.GET_PERMISSIONS); + return activity.getPackageManager().getPackageInfoAsUser( + packageName, PackageManager.GET_PERMISSIONS, userHandle); } catch (PackageManager.NameNotFoundException e) { Log.i(LOG_TAG, "No package: " + activity.getCallingPackage(), e); activity.setResult(Activity.RESULT_CANCELED); diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java index 0c4ad8239..50ea9de61 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java @@ -329,7 +329,8 @@ public class PermissionUsageFragment extends PermissionsFrameFragment implements for (int i = 0, numUsages = appPermissionUsages.size(); i < numUsages; i++) { AppPermissionUsage usage = appPermissionUsages.get(i); // Filter out entries we've seen before. - if (!addedEntries.add(usage.getPackageName() + "," + usage.getPermissionGroupName())) { + if (!addedEntries.add(usage.getPackageName() + "," + usage.getUid() + "," + + usage.getPermissionGroupName())) { continue; } PermissionApp permApp = usageToApp.get(usage); diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsagePreference.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsagePreference.java index fbfb42d27..929355d2e 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsagePreference.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsagePreference.java @@ -19,6 +19,7 @@ package com.android.packageinstaller.permission.ui.handheld; import android.content.Context; import android.content.Intent; import android.graphics.drawable.Drawable; +import android.os.UserHandle; import androidx.annotation.NonNull; import androidx.preference.Preference; @@ -52,6 +53,7 @@ public class PermissionUsagePreference extends Preference { Intent intent = new Intent(Intent.ACTION_MANAGE_APP_PERMISSION); intent.putExtra(Intent.EXTRA_PACKAGE_NAME, usage.getPackageName()); intent.putExtra(Intent.EXTRA_PERMISSION_NAME, usage.getPermissionName()); + intent.putExtra(Intent.EXTRA_USER, UserHandle.getUserHandleForUid(usage.getUid())); context.startActivity(intent); return true; }); -- GitLab From 3c8f345e7b4d1c42e5432b7c25c4ddb31afa539d Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Mon, 26 Nov 2018 07:53:21 -0800 Subject: [PATCH 150/701] Use correct icon in dark mode. Ensure AppPermissionFragment uses the correct icon in dark mode. Test: View icon in normal and dark mode. Change-Id: I31174889fb8e92655fbe891b915cfb8019dbae63 --- .../ui/handheld/AppPermissionUsageFragment.java | 4 +++- .../ui/handheld/PermissionUsagePreference.java | 13 +++---------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java index 5f1e7c40c..5a93e4246 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java @@ -187,7 +187,9 @@ public class AppPermissionUsageFragment extends SettingsWithHeader { String timeDiffStr = Utils.getTimeDiffStr(context, timeDiff); String summary = context.getString(R.string.app_permission_usage_summary, timeDiffStr); Preference pref = new PermissionUsagePreference(context, usage, - usage.getPermissionGroupLabel(), summary, group.getIconResId()); + usage.getPermissionGroupLabel(), summary, + Utils.applyTint(context, group.getIconResId(), + android.R.attr.colorControlNormal)); screen.addPreference(pref); } diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsagePreference.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsagePreference.java index fbfb42d27..e4359c5ab 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsagePreference.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsagePreference.java @@ -29,25 +29,18 @@ import com.android.packageinstaller.permission.model.AppPermissionUsage; * A preference for representing a permission usage by an app. */ public class PermissionUsagePreference extends Preference { - public PermissionUsagePreference(@NonNull Context context, @NonNull AppPermissionUsage usage, - @NonNull CharSequence title, @NonNull String summary, int iconResId) { - super(context); - updateUi(context, usage, title, summary); - setIcon(iconResId); - } - public PermissionUsagePreference(@NonNull Context context, @NonNull AppPermissionUsage usage, @NonNull CharSequence title, @NonNull String summary, @NonNull Drawable icon) { super(context); - updateUi(context, usage, title, summary); - setIcon(icon); + updateUi(context, usage, title, summary, icon); } private void updateUi(@NonNull Context context, @NonNull AppPermissionUsage usage, - @NonNull CharSequence title, @NonNull String summary) { + @NonNull CharSequence title, @NonNull String summary, @NonNull Drawable icon) { setKey(usage.getPackageName() + "," + usage.getPermissionGroupName()); setTitle(title); setSummary(summary); + setIcon(icon); setOnPreferenceClickListener(preference -> { Intent intent = new Intent(Intent.ACTION_MANAGE_APP_PERMISSION); intent.putExtra(Intent.EXTRA_PACKAGE_NAME, usage.getPackageName()); -- GitLab From e7329bba393f12dbcc5ff5d928f1a1b02c9a483c Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Sun, 18 Nov 2018 17:52:27 -0700 Subject: [PATCH 151/701] Iterate on storage permissions model. This change updates the permissions design to use app-ops for controlling write access, which is only extended to the default app for a particular collection type. Bug: 119713234 Test: atest android.appsecurity.cts.PermissionsHostTest Test: atest android.appsecurity.cts.ExternalStorageHostTest Test: atest cts/tests/tests/provider/src/android/provider/cts/MediaStore* Change-Id: I4308c12de960a0ea60c44da23269e14dcb23c30d --- res/xml/roles.xml | 75 ++++++++++++------- .../permission/utils/Utils.java | 3 - .../packageinstaller/role/model/Roles.java | 28 +++++++ 3 files changed, 74 insertions(+), 32 deletions(-) diff --git a/res/xml/roles.xml b/res/xml/roles.xml index d3626f6bd..733a19d3c 100644 --- a/res/xml/roles.xml +++ b/res/xml/roles.xml @@ -68,30 +68,13 @@ - - - - - - - - - - - - - + - - - - - - - + + @@ -179,7 +162,8 @@ - + + @@ -231,33 +215,66 @@ - + - + - + - + + + + + + + + + + + + + + + + + - + - + - + - + + + + + + + + + + + + + + + + + + diff --git a/src/com/android/packageinstaller/permission/utils/Utils.java b/src/com/android/packageinstaller/permission/utils/Utils.java index 8947babf4..baf76435b 100644 --- a/src/com/android/packageinstaller/permission/utils/Utils.java +++ b/src/com/android/packageinstaller/permission/utils/Utils.java @@ -99,12 +99,9 @@ public final class Utils { PLATFORM_PERMISSIONS.put(Manifest.permission.WRITE_EXTERNAL_STORAGE, STORAGE); PLATFORM_PERMISSIONS.put(Manifest.permission.READ_MEDIA_AUDIO, MEDIA_AURAL); - PLATFORM_PERMISSIONS.put(Manifest.permission.WRITE_MEDIA_AUDIO, MEDIA_AURAL); PLATFORM_PERMISSIONS.put(Manifest.permission.READ_MEDIA_IMAGES, MEDIA_VISUAL); - PLATFORM_PERMISSIONS.put(Manifest.permission.WRITE_MEDIA_IMAGES, MEDIA_VISUAL); PLATFORM_PERMISSIONS.put(Manifest.permission.READ_MEDIA_VIDEO, MEDIA_VISUAL); - PLATFORM_PERMISSIONS.put(Manifest.permission.WRITE_MEDIA_VIDEO, MEDIA_VISUAL); PLATFORM_PERMISSIONS.put(Manifest.permission.ACCESS_MEDIA_LOCATION, MEDIA_VISUAL); PLATFORM_PERMISSIONS.put(Manifest.permission.ACCESS_FINE_LOCATION, LOCATION); diff --git a/src/com/android/packageinstaller/role/model/Roles.java b/src/com/android/packageinstaller/role/model/Roles.java index eef7bb77f..bc86e6b59 100644 --- a/src/com/android/packageinstaller/role/model/Roles.java +++ b/src/com/android/packageinstaller/role/model/Roles.java @@ -20,6 +20,7 @@ import android.app.AppOpsManager; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.XmlResourceParser; import android.util.ArrayMap; import android.util.Log; @@ -97,6 +98,8 @@ public class Roles { @Nullable private static ArrayMap sRoles; + private static boolean sIsolatedStorage; + private Roles() {} /** @@ -118,6 +121,17 @@ public class Roles { @NonNull private static ArrayMap loadRoles(@NonNull Context context) { + // If the storage model feature flag is disabled, we need to fiddle + // around with permission definitions to return us to pre-Q behavior. + // STOPSHIP(b/112545973): remove once feature enabled by default + try { + context.getPackageManager() + .getPermissionInfo(android.Manifest.permission.READ_MEDIA_AUDIO, 0); + sIsolatedStorage = true; + } catch (NameNotFoundException e) { + sIsolatedStorage = false; + } + try (XmlResourceParser parser = context.getResources().getXml(R.xml.roles)) { Pair, ArrayMap> xml = parseXml(parser); if (xml == null) { @@ -580,6 +594,20 @@ public class Roles { } } + // If the storage model feature flag is disabled, we need to fiddle + // around with permission definitions to return us to pre-Q behavior. + // STOPSHIP(b/112545973): remove once feature enabled by default + if (!sIsolatedStorage) { + boolean removed = false; + removed |= permissions.remove(android.Manifest.permission.READ_MEDIA_AUDIO); + removed |= permissions.remove(android.Manifest.permission.READ_MEDIA_VIDEO); + removed |= permissions.remove(android.Manifest.permission.READ_MEDIA_IMAGES); + if (removed) { + permissions.add(android.Manifest.permission.READ_EXTERNAL_STORAGE); + permissions.add(android.Manifest.permission.WRITE_EXTERNAL_STORAGE); + } + } + return permissions; } -- GitLab From 0c5a8a72faa7debbe6fbf68bd10d5ce96216aac3 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Mon, 26 Nov 2018 13:37:26 -0800 Subject: [PATCH 152/701] Replace my new API with an existing one. jsharkey pointed out an existing way to get PackageInfos for different users, so let's use that instead. Bug: 119811056 Test: Setup work profile, use both Contacts apps, give them different permissions, then see separate entries in PermissionUsageFragment and verify that AppPermissionFragment can change either app's permissions. Change-Id: Ibe3ce8c191cda689fc6633d2a135f37342e3b2e8 --- .../permission/ui/handheld/AppPermissionFragment.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java index 044c2c1e7..8b99cd532 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java @@ -228,7 +228,8 @@ public class AppPermissionFragment extends PermissionsFrameFragment { // Check if the package was removed while this activity was not started. try { - pm.getPackageInfoAsUser(packageName, 0, userHandle); + activity.createPackageContextAsUser( + packageName, 0, userHandle).getPackageManager().getPackageInfo(packageName, 0); } catch (NameNotFoundException e) { Log.w(LOG_TAG, packageName + " was uninstalled while this activity was stopped", e); activity.setResult(Activity.RESULT_CANCELED); @@ -410,8 +411,9 @@ public class AppPermissionFragment extends PermissionsFrameFragment { private static @Nullable PackageInfo getPackageInfo(@NonNull Activity activity, @NonNull String packageName, @NonNull UserHandle userHandle) { try { - return activity.getPackageManager().getPackageInfoAsUser( - packageName, PackageManager.GET_PERMISSIONS, userHandle); + return activity.createPackageContextAsUser(packageName, 0, + userHandle).getPackageManager().getPackageInfo(packageName, + PackageManager.GET_PERMISSIONS); } catch (PackageManager.NameNotFoundException e) { Log.i(LOG_TAG, "No package: " + activity.getCallingPackage(), e); activity.setResult(Activity.RESULT_CANCELED); -- GitLab From 775e4ab6530dead458be7b645b459e85c8971d9c Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Mon, 26 Nov 2018 16:41:49 -0800 Subject: [PATCH 153/701] Make request role dialog cancelable. This change makes the request role dialog to be cancelable, and added some logging before finish() is called. Bug: 110557011 Test: build Change-Id: I172eefc3d1a65329afde91715c538496ec851e80 --- res/values/themes.xml | 1 - .../role/ui/RequestRoleFragment.java | 15 ++++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/res/values/themes.xml b/res/values/themes.xml index cba680047..a7bfa758f 100644 --- a/res/values/themes.xml +++ b/res/values/themes.xml @@ -44,7 +44,6 @@ diff --git a/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java b/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java index dc9e42846..955b01d6a 100644 --- a/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java +++ b/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java @@ -122,16 +122,19 @@ public class RequestRoleFragment extends DialogFragment { } CharSequence message = Html.fromHtml(messageHtml, Html.FROM_HTML_MODE_LEGACY); - // Set the button listeners later to get rid of the automatic dismiss behavior. AlertDialog dialog = new AlertDialog.Builder(context, getTheme()) .setMessage(message) + // Set the positive button listener later to avoid the automatic dismiss behavior. .setPositiveButton(android.R.string.ok, null) .setNegativeButton(android.R.string.cancel, null) + .setOnDismissListener(dialog2 -> { + Log.i(LOG_TAG, "Dialog dismissed, role: " + mRoleName + ", package: " + + mPackageName); + finish(); + }) .create(); - dialog.setOnShowListener(dialog2 -> { - dialog.getButton(Dialog.BUTTON_POSITIVE).setOnClickListener(view -> addRoleHolder()); - dialog.getButton(Dialog.BUTTON_NEGATIVE).setOnClickListener(view -> finish()); - }); + dialog.setOnShowListener(dialog2 -> dialog.getButton(Dialog.BUTTON_POSITIVE) + .setOnClickListener(view -> addRoleHolder())); return dialog; } @@ -150,6 +153,8 @@ public class RequestRoleFragment extends DialogFragment { mPackageRemovalMonitor = new PackageRemovalMonitor(requireContext(), mPackageName) { @Override protected void onPackageRemoved() { + Log.w(LOG_TAG, "Application is uninstalled, role: " + mRoleName + ", package: " + + mPackageName); finish(); } }; -- GitLab From a5c4b891677e585fa7f0cbf334ae4e73b50bad36 Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Tue, 27 Nov 2018 17:00:23 -0800 Subject: [PATCH 154/701] Do not use action to start AppPermissionFragment Test: Opened AppPermissionFragment Change-Id: I4422ab1b200f0e0a4f232258cc15236dd6503e26 --- AndroidManifest.xml | 6 +- .../permission/ui/AppPermissionActivity.java | 87 +++++++++++++++++++ .../ui/ManagePermissionsActivity.java | 27 +----- .../handheld/PermissionUsagePreference.java | 3 +- 4 files changed, 95 insertions(+), 28 deletions(-) create mode 100644 src/com/android/packageinstaller/permission/ui/AppPermissionActivity.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 7c52c51f0..ad82f0b62 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -55,7 +55,6 @@ android:theme="@style/Settings" android:permission="android.permission.GRANT_RUNTIME_PERMISSIONS"> - @@ -74,6 +73,11 @@ + + { - Intent intent = new Intent(Intent.ACTION_MANAGE_APP_PERMISSION); + Intent intent = new Intent(context, AppPermissionActivity.class); intent.putExtra(Intent.EXTRA_PACKAGE_NAME, usage.getPackageName()); intent.putExtra(Intent.EXTRA_PERMISSION_NAME, usage.getPermissionName()); intent.putExtra(Intent.EXTRA_USER, UserHandle.getUserHandleForUid(usage.getUid())); -- GitLab From 5388d0b54d50f09347d4abf9a804812bd1b90488 Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Thu, 29 Nov 2018 10:31:40 -0800 Subject: [PATCH 155/701] Add uses-sdk for permission controller. This change adds the in the manifest for permission controller. Bug: 120183702 Test: build Change-Id: Id1b41f18bb65d812a30ca7a0c3e021884ee66148 --- AndroidManifest.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 7c52c51f0..03ae460ba 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -30,6 +30,8 @@ + + Date: Fri, 30 Nov 2018 12:43:25 -0800 Subject: [PATCH 156/701] Ignore 'UNDEFINED' group This group is only there to prevent crashing is poorly written apps. Test: Looked at permissions controller UI. No change to before Bug: 119836955 Change-Id: I723817df52dcc891ff95ddfab4fc84f6666163e5 --- .../permission/model/PermissionGroups.java | 12 ++++++++++++ .../packageinstaller/permission/utils/Utils.java | 4 ++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/com/android/packageinstaller/permission/model/PermissionGroups.java b/src/com/android/packageinstaller/permission/model/PermissionGroups.java index 257d36e9c..93e92d572 100644 --- a/src/com/android/packageinstaller/permission/model/PermissionGroups.java +++ b/src/com/android/packageinstaller/permission/model/PermissionGroups.java @@ -19,6 +19,7 @@ package com.android.packageinstaller.permission.model; import static android.content.pm.PackageItemInfo.SAFE_LABEL_FLAG_FIRST_LINE; import static android.content.pm.PackageItemInfo.SAFE_LABEL_FLAG_TRIM; +import android.Manifest; import android.app.LoaderManager; import android.app.LoaderManager.LoaderCallbacks; import android.content.AsyncTaskLoader; @@ -248,6 +249,17 @@ public final class PermissionGroups implements LoaderCallbacks Date: Fri, 30 Nov 2018 17:27:37 -0800 Subject: [PATCH 157/701] Remove non-required components for the SMS role. This change removes the non-required components for the SMS role. Although they are looked up by SmsApplication, they are not required according to SmsApplicationData.isComplete(). Bug: 110557011 Test: manual Change-Id: I53763979b266fd8bb21fdf2544bf35e013ac29fb --- res/xml/roles.xml | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/res/xml/roles.xml b/res/xml/roles.xml index 4101da1b2..154f6b637 100644 --- a/res/xml/roles.xml +++ b/res/xml/roles.xml @@ -159,21 +159,6 @@ - - - - - - - - - - - - - - - -- GitLab From 1e9323e37563ed4e7334b1cb8b59f3a8bd2b59de Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Wed, 21 Nov 2018 12:47:42 -0800 Subject: [PATCH 158/701] Show location access notifications The notifications double guess the user if she/he granted fine background location access to and app. Fixes: 120303361 Test: atest CtsPermissionTestCases:android.permission.cts.LocationAccessCheckTest Change-Id: I77fbe61522750b737feb70fac57d2f7ddf954db4 --- AndroidManifest.xml | 21 + res/drawable/ic_signal_location.xml | 29 + res/values/strings.xml | 9 + .../android/packageinstaller/Constants.java | 66 ++ .../permission/model/AppPermissionGroup.java | 52 +- .../service/LocationAccessCheck.java | 828 ++++++++++++++++++ .../permission/utils/LocationUtils.java | 10 +- .../permission/utils/Utils.java | 43 + 8 files changed, 1056 insertions(+), 2 deletions(-) create mode 100644 res/drawable/ic_signal_location.xml create mode 100644 src/com/android/packageinstaller/Constants.java create mode 100644 src/com/android/packageinstaller/permission/service/LocationAccessCheck.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index e8e56ad91..aace6dfc8 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -40,6 +40,27 @@ android:defaultToDeviceProtectedStorage="true" android:directBootAware="true"> + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/values/strings.xml b/res/values/strings.xml index 7be986bd7..70ee60594 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -332,6 +332,15 @@ <b>%1$s</b> as your %2$s? + + Permission reminders + + + %s has been using your location + + + This app can always access your location. Tap to change. + diff --git a/src/com/android/packageinstaller/Constants.java b/src/com/android/packageinstaller/Constants.java new file mode 100644 index 000000000..4c3cc028b --- /dev/null +++ b/src/com/android/packageinstaller/Constants.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.packageinstaller; + +/** + * App-global constants + */ +public class Constants { + /** + * ID for the periodic job in + * {@link com.android.packageinstaller.permission.service.LocationAccessCheck}. + */ + public static final int PERIODIC_LOCATION_ACCESS_CHECK_JOB_ID = 0; + + /** + * ID for the on-demand, but delayed job in + * {@link com.android.packageinstaller.permission.service.LocationAccessCheck}. + */ + public static final int LOCATION_ACCESS_CHECK_JOB_ID = 1; + + /** + * Name of file to containing the packages we already showed a notificaiton for. + * + * @see com.android.packageinstaller.permission.service.LocationAccessCheck + */ + public static final String LOCATION_ACCESS_CHECK_ALREADY_NOTIFIED_FILE = + "packages_already_notified_location_access"; + + /** + * ID for notification shown by + * {@link com.android.packageinstaller.permission.service.LocationAccessCheck}. + */ + public static final int LOCATION_ACCESS_CHECK_NOTIFICATION_ID = 0; + + /** + * Channel of the notifications shown by + * {@link com.android.packageinstaller.permission.service.LocationAccessCheck}. + */ + public static final String PERMISSION_REMINDER_CHANNEL_ID = "permission reminders"; + + /** + * Name of generic shared preferences file. + */ + public static final String PREFERENCES_FILE = "preferences"; + + /** + * Key in the generic shared preferences that stores when the last notification was shown by + * {@link com.android.packageinstaller.permission.service.LocationAccessCheck} + */ + public static final String KEY_LAST_LOCATION_ACCESS_NOTIFICATION_SHOWN = + "last_location_access_notification_shown"; +} diff --git a/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java b/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java index 147cdf415..bef65d459 100644 --- a/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java +++ b/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java @@ -16,10 +16,15 @@ package com.android.packageinstaller.permission.model; +import static android.Manifest.permission.ACCESS_BACKGROUND_LOCATION; +import static android.Manifest.permission.ACCESS_FINE_LOCATION; import static android.app.AppOpsManager.MODE_ALLOWED; import static android.app.AppOpsManager.MODE_FOREGROUND; import static android.app.AppOpsManager.MODE_IGNORED; +import static com.android.packageinstaller.permission.service.LocationAccessCheck + .checkLocationAccessSoon; + import android.app.ActivityManager; import android.app.AppOpsManager; import android.content.Context; @@ -34,6 +39,8 @@ import android.os.UserHandle; import android.provider.Settings; import android.util.ArrayMap; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.annotation.StringRes; import com.android.packageinstaller.permission.utils.ArrayUtils; @@ -191,7 +198,8 @@ public final class AppPermissionGroup implements Comparable // Parse and create permissions reqested by the app ArrayMap allPermissions = new ArrayMap<>(); - final int permissionCount = packageInfo.requestedPermissions.length; + final int permissionCount = packageInfo.requestedPermissions == null ? 0 + : packageInfo.requestedPermissions.length; String packageName = packageInfo.packageName; for (int i = 0; i < permissionCount; i++) { String requestedPermission = packageInfo.requestedPermissions[i]; @@ -592,6 +600,17 @@ public final class AppPermissionGroup implements Comparable return mPermissions.get(permission) != null; } + /** + * Return a permission if in this group. + * + * @param permissionName The name of the permission + * + * @return The permission + */ + public @Nullable Permission getPermission(@NonNull String permissionName) { + return mPermissions.get(permissionName); + } + public boolean areRuntimePermissionsGranted() { return areRuntimePermissionsGranted(null); } @@ -720,6 +739,8 @@ public final class AppPermissionGroup implements Comparable continue; } + boolean wasGranted = permission.isGranted() && permission.isAppOpAllowed(); + if (mAppSupportsRuntimePermissions) { // Do not touch permissions fixed by the system. if (permission.isSystemFixed()) { @@ -778,6 +799,35 @@ public final class AppPermissionGroup implements Comparable permission.resetReviewRequired(); } } + + // If we newly grant background access to the fine location, double-guess the user some + // time later if this was really the right choice. + if (!wasGranted && !(permission.isGranted() && permission.isAppOpAllowed())) { + if (mName.equals(ACCESS_FINE_LOCATION)) { + Permission bgPerm = permission.getBackgroundPermission(); + if (bgPerm != null) { + if (bgPerm.isGranted() && bgPerm.isAppOpAllowed()) { + checkLocationAccessSoon(mContext); + } + } + } else if (mName.equals(ACCESS_BACKGROUND_LOCATION)) { + ArrayList fgPerms = permission.getForegroundPermissions(); + if (fgPerms != null) { + int numFgPerms = fgPerms.size(); + for (int fgPermNum = 0; fgPermNum < numFgPerms; fgPermNum++) { + Permission fgPerm = fgPerms.get(fgPermNum); + + if (fgPerm.getName().equals(ACCESS_FINE_LOCATION)) { + if (fgPerm.isGranted() && fgPerm.isAppOpAllowed()) { + checkLocationAccessSoon(mContext); + } + + break; + } + } + } + } + } } if (!mDelayChanges) { diff --git a/src/com/android/packageinstaller/permission/service/LocationAccessCheck.java b/src/com/android/packageinstaller/permission/service/LocationAccessCheck.java new file mode 100644 index 000000000..eef1ec316 --- /dev/null +++ b/src/com/android/packageinstaller/permission/service/LocationAccessCheck.java @@ -0,0 +1,828 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.packageinstaller.permission.service; + +import static android.Manifest.permission.ACCESS_BACKGROUND_LOCATION; +import static android.Manifest.permission.ACCESS_FINE_LOCATION; +import static android.app.AppOpsManager.OPSTR_FINE_LOCATION; +import static android.app.NotificationManager.IMPORTANCE_LOW; +import static android.app.PendingIntent.FLAG_ONE_SHOT; +import static android.app.PendingIntent.FLAG_UPDATE_CURRENT; +import static android.app.PendingIntent.getBroadcast; +import static android.app.job.JobScheduler.RESULT_SUCCESS; +import static android.content.Intent.EXTRA_PACKAGE_NAME; +import static android.content.Intent.EXTRA_PERMISSION_NAME; +import static android.content.Intent.EXTRA_UID; +import static android.content.Intent.EXTRA_USER; +import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; +import static android.content.pm.PackageManager.GET_PERMISSIONS; +import static android.graphics.Bitmap.Config.ARGB_8888; +import static android.graphics.Bitmap.createBitmap; +import static android.os.UserHandle.getUserHandleForUid; +import static android.os.UserHandle.myUserId; +import static android.provider.Settings.Secure.LOCATION_ACCESS_CHECK_DELAY_MILLIS; +import static android.provider.Settings.Secure.LOCATION_ACCESS_CHECK_INTERVAL_MILLIS; + +import static com.android.packageinstaller.Constants.KEY_LAST_LOCATION_ACCESS_NOTIFICATION_SHOWN; +import static com.android.packageinstaller.Constants.LOCATION_ACCESS_CHECK_ALREADY_NOTIFIED_FILE; +import static com.android.packageinstaller.Constants.LOCATION_ACCESS_CHECK_JOB_ID; +import static com.android.packageinstaller.Constants.LOCATION_ACCESS_CHECK_NOTIFICATION_ID; +import static com.android.packageinstaller.Constants.PERIODIC_LOCATION_ACCESS_CHECK_JOB_ID; +import static com.android.packageinstaller.Constants.PERMISSION_REMINDER_CHANNEL_ID; +import static com.android.packageinstaller.Constants.PREFERENCES_FILE; +import static com.android.packageinstaller.permission.utils.LocationUtils.isNetworkLocationProvider; +import static com.android.packageinstaller.permission.utils.Utils.OS_PKG; +import static com.android.packageinstaller.permission.utils.Utils.getParcelableExtraSafe; +import static com.android.packageinstaller.permission.utils.Utils.getStringExtraSafe; +import static com.android.packageinstaller.permission.utils.Utils.getSystemServiceSafe; + +import static java.lang.System.currentTimeMillis; +import static java.util.concurrent.TimeUnit.DAYS; +import static java.util.concurrent.TimeUnit.MINUTES; + +import android.app.AppOpsManager; +import android.app.AppOpsManager.HistoricalOpEntry; +import android.app.AppOpsManager.HistoricalPackageOps; +import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.job.JobInfo; +import android.app.job.JobParameters; +import android.app.job.JobScheduler; +import android.app.job.JobService; +import android.content.BroadcastReceiver; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.os.AsyncTask; +import android.os.UserHandle; +import android.os.UserManager; +import android.provider.Settings; +import android.service.notification.StatusBarNotification; +import android.util.ArraySet; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.core.util.Preconditions; + +import com.android.packageinstaller.permission.model.AppPermissionGroup; +import com.android.packageinstaller.permission.model.Permission; +import com.android.packageinstaller.permission.ui.AppPermissionActivity; +import com.android.permissioncontroller.R; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Random; + +/** + * Show notification that double-guesses the user if she/he really wants to grant fine background + * location access to an app. + * + *

A notification is scheduled after the background permission access is granted via + * {@link #checkLocationAccessSoon(Context)} or periodically. + * + *

We rate limit the number of notification we show and only ever show one notification at a + * time. Further we only shown notifications if the app has actually accessed the fine location + * in the background. + * + *

As there are many cases why a notification should not been shown, we always schedule a + * {@link #addLocationNotificationIfNeeded check} which then might add a notification. + */ +public class LocationAccessCheck extends JobService { + private static final String LOG_TAG = LocationAccessCheck.class.getSimpleName(); + private static final boolean DEBUG = false; + + /** Lock required for all methods called {@code ...Locked} */ + private static final Object sLock = new Object(); + + private final Random mRandom = new Random(); + + /* Initialized late in {@link #onCreate} */ + private NotificationManager mNotificationManager; + private AppOpsManager mAppOpsManager; + private PackageManager mPackageManager; + private UserManager mUserManager; + private SharedPreferences mSharedPrefs; + + /** If we currently check if we should show a notification, the task executing the check */ + // @GuardedBy("sLock") + private @Nullable AddLocationNotificationIfNeededTask mAddLocationNotificationIfNeededTask; + + /** + * Get time in between two periodic checks. + * + *

Default: 1 day + * + * @param context Context used to resolve settings + * + * @return The time in between check in milliseconds + */ + private static long getPeriodicCheckIntervalMillis(@NonNull Context context) { + return Settings.Secure.getLong(context.getContentResolver(), + LOCATION_ACCESS_CHECK_INTERVAL_MILLIS, DAYS.toMillis(1)); + } + + /** + * Flexibility of the periodic check. + * + *

10% of {@link #getPeriodicCheckIntervalMillis(Context)} + * + * @param context Context used to resolve settings + * + * @return The flexibility of the periodic check in milliseconds + */ + private static long getFlexForPeriodicCheckMillis(@NonNull Context context) { + return getPeriodicCheckIntervalMillis(context) / 10; + } + + /** + * Get the delay in between granting a permission and the follow up check. + * + *

Default: 10 minutes + * + * @param context Context used to resolve settings + * + * @return The delay in milliseconds + */ + private static long getDelayMillis(@NonNull Context context) { + return Settings.Secure.getLong(context.getContentResolver(), + LOCATION_ACCESS_CHECK_DELAY_MILLIS, MINUTES.toMillis(10)); + } + + /** + * Minimum time in between showing two notifications. + * + *

This is just small enough so that the periodic check can always show a notification. + * + * @param context Context used to resolve settings + * + * @return The minimum time in milliseconds + */ + private static long getInBetweenNotificationsMillis(@NonNull Context context) { + return getPeriodicCheckIntervalMillis(context) - (long) (getFlexForPeriodicCheckMillis( + context) * 2.1); + } + + /** + * Load the list of {@link UserPackage packages} we already shown a notification for. + * + * @param context A context used to resolve managers. + * + * @return The list of packages we already shown a notification for. + */ + private static @NonNull ArraySet loadAlreadyNotifiedPackagesLocked( + @NonNull Context context) { + UserManager userManager = context.getSystemService(UserManager.class); + + try (BufferedReader reader = new BufferedReader(new InputStreamReader(context.openFileInput( + LOCATION_ACCESS_CHECK_ALREADY_NOTIFIED_FILE)))) { + ArraySet packages = new ArraySet<>(); + + /* + * The format of the file is , e.g. + * + * com.one.package 5630633845 + * com.two.package 5630633853 + * com.three.package 5630633853 + */ + while (true) { + String line = reader.readLine(); + if (line == null) { + break; + } + + String[] lineComponents = line.split(" "); + String pkg = lineComponents[0]; + UserHandle user = userManager.getUserForSerialNumber( + Long.valueOf(lineComponents[1])); + + if (user != null) { + packages.add(new UserPackage(pkg, user)); + } else { + Log.i(LOG_TAG, "Not restoring state \"" + line + "\" as user is unknown"); + } + } + + return packages; + } catch (FileNotFoundException ignored) { + return new ArraySet<>(); + } catch (Exception e) { + Log.w(LOG_TAG, "Could not read " + LOCATION_ACCESS_CHECK_ALREADY_NOTIFIED_FILE, e); + return new ArraySet<>(); + } + } + + /** + * Safe the list of {@link UserPackage packages} we have already shown a notification for. + * + * @param context A context used to resolve managers. + * @param packages The list of packages we already shown a notification for. + */ + private static void safeAlreadyNotifiedPackagesLocked(@NonNull Context context, + @NonNull ArraySet packages) { + UserManager userManager = getSystemServiceSafe(context, UserManager.class); + + try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter( + context.openFileOutput(LOCATION_ACCESS_CHECK_ALREADY_NOTIFIED_FILE, + MODE_PRIVATE)))) { + /* + * The format of the file is , e.g. + * + * com.one.package 5630633845 + * com.two.package 5630633853 + * com.three.package 5630633853 + */ + int numPkgs = packages.size(); + for (int i = 0; i < numPkgs; i++) { + UserPackage userPkg = packages.valueAt(i); + + writer.append(userPkg.pkg); + writer.append(' '); + writer.append( + Long.valueOf(userManager.getSerialNumberForUser(userPkg.user)).toString()); + writer.newLine(); + } + } catch (IOException e) { + Log.e(LOG_TAG, "Could not write " + LOCATION_ACCESS_CHECK_ALREADY_NOTIFIED_FILE, e); + } + } + + /** + * Remember that we showed a notification for a {@link UserPackage} + * + * @param context Context used to resolve manager + * @param pkg The package we notified for + * @param user The user we notified for + */ + private static void markAsNotified(@NonNull Context context, @NonNull String pkg, + @NonNull UserHandle user) { + synchronized (sLock) { + ArraySet alreadyNotifiedPackages = loadAlreadyNotifiedPackagesLocked( + context); + alreadyNotifiedPackages.add(new UserPackage(pkg, user)); + safeAlreadyNotifiedPackagesLocked(context, alreadyNotifiedPackages); + } + } + + /** + * Create the channel the location access notifications should be posted to. + * + * @param user The user to create the channel for + */ + private void createPermissionReminderChannel(@NonNull UserHandle user) { + NotificationManager notificationManager = getSystemServiceSafe(this, + NotificationManager.class, user); + + NotificationChannel permissionReminderChannel = new NotificationChannel( + PERMISSION_REMINDER_CHANNEL_ID, getString(R.string.permission_reminders), + IMPORTANCE_LOW); + notificationManager.createNotificationChannel(permissionReminderChannel); + } + + /** + * If the {@link #mAddLocationNotificationIfNeededTask} is canceled, throw a + * {@link InterruptedException}. + */ + private void throwInterruptedExceptionIfTaskIsCanceledLocked() throws InterruptedException { + AddLocationNotificationIfNeededTask task = mAddLocationNotificationIfNeededTask; + if (task != null && task.isCancelled()) { + throw new InterruptedException(); + } + } + + @Override + public void onCreate() { + super.onCreate(); + + mNotificationManager = getSystemService(NotificationManager.class); + mAppOpsManager = getSystemService(AppOpsManager.class); + mPackageManager = getPackageManager(); + mUserManager = getSystemService(UserManager.class); + mSharedPrefs = getSharedPreferences(PREFERENCES_FILE, MODE_PRIVATE); + } + + /** + * Starts an asynchronous {@link #addLocationNotificationIfNeeded() check} if a location access + * notification should be shown. + * + * @param params Not used other than for interacting with job scheduling + * + * @return {@code false} iff another check if already running + */ + @Override + public boolean onStartJob(JobParameters params) { + synchronized (sLock) { + if (mAddLocationNotificationIfNeededTask != null) { + return false; + } + + mAddLocationNotificationIfNeededTask = new AddLocationNotificationIfNeededTask(); + } + + mAddLocationNotificationIfNeededTask.execute(this, params); + + return true; + } + + /** + * Abort the {@link #addLocationNotificationIfNeeded() check} if still running. + * + * @param params ignored + * + * @return false + */ + @Override + public boolean onStopJob(JobParameters params) { + AddLocationNotificationIfNeededTask task; + synchronized (sLock) { + if (mAddLocationNotificationIfNeededTask == null) { + return false; + } else { + task = mAddLocationNotificationIfNeededTask; + } + } + + task.cancel(false); + + try { + // Wait for task to finish + task.get(); + } catch (Exception e) { + Log.e(LOG_TAG, "While waiting for " + task + " to finish", e); + } + + return false; + } + + /** + * Check if a location access notification should be shown and then add it. + * + *

Always run async inside a {@link AddLocationNotificationIfNeededTask}. + * + * @throws InterruptedException If the {@link #mAddLocationNotificationIfNeededTask} has been + * canceled. + */ + private void addLocationNotificationIfNeeded() throws InterruptedException { + synchronized (sLock) { + if (currentTimeMillis() - mSharedPrefs.getLong( + KEY_LAST_LOCATION_ACCESS_NOTIFICATION_SHOWN, 0) + < getInBetweenNotificationsMillis(this)) { + return; + } + + if (getCurrentlyShownNotificationLocked(this) != null) { + return; + } + + List packages = getLocationUsersWithNoNotificationYetLocked(); + + // Get a random package and resolve package info + PackageInfo pkgInfo = null; + while (pkgInfo == null) { + if (packages.isEmpty()) { + return; + } + + UserPackage packageToNotifyFor = null; + + // Prefer location history + /* TODO: Enable once we know the location history package + int numPkgs = packages.size(); + for (int i = 0; i < numPkgs; i++) { + UserPackage pkg = packages.get(i); + + if (pkg.pkg.equals(getSystemServiceSafe(this, LocationManager.class, + pkg.user).getLocationHistoryProviderPackage())) { + packageToNotifyFor = pkg; + } + } + */ + + if (packageToNotifyFor == null) { + packageToNotifyFor = packages.get(mRandom.nextInt(packages.size())); + } + + try { + pkgInfo = packageToNotifyFor.getPackageInfo(this); + } catch (PackageManager.NameNotFoundException e) { + packages.remove(packageToNotifyFor); + } + + createPermissionReminderChannel(packageToNotifyFor.user); + } + + createNotificationForLocationUser(pkgInfo); + } + } + + /** + * Get the {@link UserPackage packages} which accessed the location but we have not yet shown + * a notification for. + * + * @return The packages we need to show a notification for + * + * @throws InterruptedException If the {@link #mAddLocationNotificationIfNeededTask} is canceled + */ + private @NonNull List getLocationUsersWithNoNotificationYetLocked() + throws InterruptedException { + List pkgsWithLocationAccess = new ArrayList<>(); + List profiles = mUserManager.getUserProfiles(); + + List pkgOps = mAppOpsManager.getAllHistoricPackagesOps( + new String[]{OPSTR_FINE_LOCATION}, 0, System.currentTimeMillis()); + + int numPkgOps = pkgOps.size(); + for (int pkgOpsNum = 0; pkgOpsNum < numPkgOps; pkgOpsNum++) { + HistoricalPackageOps ops = pkgOps.get(pkgOpsNum); + + String pkg = ops.getPackageName(); + if (pkg.equals(OS_PKG) || isNetworkLocationProvider(this, pkg)) { + continue; + } + + UserHandle user = getUserHandleForUid(ops.getUid()); + if (!profiles.contains(user)) { + continue; + } + + int numEntries = ops.getEntryCount(); + for (int entryNum = 0; entryNum < numEntries; entryNum++) { + HistoricalOpEntry entry = ops.getEntryAt(entryNum); + + if (entry.getBackgroundAccessCount() > 0) { + pkgsWithLocationAccess.add(new UserPackage(pkg, user)); + + break; + } + } + } + + ArraySet alreadyNotifiedPkgs = loadAlreadyNotifiedPackagesLocked(this); + throwInterruptedExceptionIfTaskIsCanceledLocked(); + + resetAlreadyNotifiedPackagesWithoutPermissionLocked(alreadyNotifiedPkgs); + + pkgsWithLocationAccess.removeAll(alreadyNotifiedPkgs); + return pkgsWithLocationAccess; + } + + /** + * Create a notification reminding the user that a package used the location. From this + * notification the user can directly go to the screen that allows to change the permission. + * + * @param pkg The {@link PackageInfo} for the package to to be changed + */ + private void createNotificationForLocationUser(@NonNull PackageInfo pkg) { + CharSequence pkgLabel = mPackageManager.getApplicationLabel(pkg.applicationInfo); + Drawable pkgIcon = mPackageManager.getApplicationIcon(pkg.applicationInfo); + Bitmap pkgIconBmp = createBitmap(pkgIcon.getIntrinsicWidth(), pkgIcon.getIntrinsicHeight(), + ARGB_8888); + pkgIcon.draw(new Canvas(pkgIconBmp)); + + String pkgName = pkg.packageName; + UserHandle user = getUserHandleForUid(pkg.applicationInfo.uid); + + NotificationManager notificationManager = getSystemServiceSafe(this, + NotificationManager.class, user); + + Intent deleteIntent = new Intent(this, NotificationDeleteHandler.class); + deleteIntent.putExtra(EXTRA_PACKAGE_NAME, pkgName); + deleteIntent.putExtra(EXTRA_USER, user); + + Intent clickIntent = new Intent(this, NotificationClickHandler.class); + clickIntent.putExtra(EXTRA_PACKAGE_NAME, pkgName); + clickIntent.putExtra(EXTRA_USER, user); + + Notification.Builder b = (new Notification.Builder(this, PERMISSION_REMINDER_CHANNEL_ID)) + .setContentTitle(getString( + R.string.background_location_access_reminder_notification_title, pkgLabel)) + .setContentText(getString( + R.string.background_location_access_reminder_notification_content)) + .setSmallIcon(R.drawable.ic_signal_location) + .setLargeIcon(pkgIconBmp) + .setAutoCancel(true) + .setDeleteIntent(getBroadcast(this, 0, deleteIntent, + FLAG_ONE_SHOT | FLAG_UPDATE_CURRENT)) + .setContentIntent(getBroadcast(this, 0, clickIntent, + FLAG_ONE_SHOT | FLAG_UPDATE_CURRENT)); + notificationManager.notify(pkgName, LOCATION_ACCESS_CHECK_NOTIFICATION_ID, b.build()); + + if (DEBUG) Log.i(LOG_TAG, "Notified " + pkgName); + + mSharedPrefs.edit().putLong(KEY_LAST_LOCATION_ACCESS_NOTIFICATION_SHOWN, + currentTimeMillis()).apply(); + } + + /** + * Get currently shown notification. We only ever show one notification per profile group. + * + * @param context A context to resolve managers + * + * @return The notification or {@code null} if no notification is currently shown + */ + private static @Nullable StatusBarNotification getCurrentlyShownNotificationLocked( + @NonNull Context context) { + UserManager userManager = getSystemServiceSafe(context, UserManager.class); + + List profiles = userManager.getUserProfiles(); + + int numProfiles = profiles.size(); + for (int profileNum = 0; profileNum < numProfiles; profileNum++) { + NotificationManager notificationManager = getSystemServiceSafe(context, + NotificationManager.class, profiles.get(profileNum)); + + StatusBarNotification[] notifications = notificationManager.getActiveNotifications(); + + int numNotifications = notifications.length; + for (int notificationNum = 0; notificationNum < numNotifications; notificationNum++) { + StatusBarNotification notification = notifications[notificationNum]; + + if (notification.getId() == LOCATION_ACCESS_CHECK_NOTIFICATION_ID) { + return notification; + } + } + } + + return null; + } + + /** + * Go through the list of packages we already shown a notification for and remove those that do + * not request fine background location access. + * + * @param alreadyNotifiedPkgs The packages we already shown a notification for. This paramter is + * modified inside of this method. + * + * @throws InterruptedException If the {@link #mAddLocationNotificationIfNeededTask} is canceled + */ + private void resetAlreadyNotifiedPackagesWithoutPermissionLocked( + @NonNull ArraySet alreadyNotifiedPkgs) throws InterruptedException { + ArrayList packagesToRemove = new ArrayList<>(); + + for (UserPackage userPkg : alreadyNotifiedPkgs) { + PackageInfo pkgInfo; + try { + pkgInfo = userPkg.getPackageInfo(this); + } catch (PackageManager.NameNotFoundException e) { + packagesToRemove.add(userPkg); + continue; + } + + AppPermissionGroup locationGroup = AppPermissionGroup.create(this, pkgInfo, + ACCESS_FINE_LOCATION, false); + throwInterruptedExceptionIfTaskIsCanceledLocked(); + + if (locationGroup == null) { + // All permission of the group have been removed + packagesToRemove.add(userPkg); + } else { + Permission fgPerm = locationGroup.getPermission(ACCESS_FINE_LOCATION); + + Permission bgPerm = null; + AppPermissionGroup bgPerms = locationGroup.getBackgroundPermissions(); + if (bgPerms != null) { + bgPerm = bgPerms.getPermission(ACCESS_BACKGROUND_LOCATION); + } + + // Individual permission have been removed + if (fgPerm == null || bgPerm == null + // Permissions are not granted + || !fgPerm.isGranted() || !fgPerm.isAppOpAllowed() + || !bgPerm.isGranted() || !bgPerm.isAppOpAllowed()) { + packagesToRemove.add(userPkg); + } + } + } + + if (!packagesToRemove.isEmpty()) { + alreadyNotifiedPkgs.removeAll(packagesToRemove); + safeAlreadyNotifiedPackagesLocked(this, alreadyNotifiedPkgs); + throwInterruptedExceptionIfTaskIsCanceledLocked(); + } + } + + /** + * Remove all persisted state for a package. + * + * @param context Context to the use + * @param pkg name of package + * @param user user the package belongs to + */ + private static void forgetAboutPackage(@NonNull Context context, @NonNull String pkg, + @NonNull UserHandle user) { + synchronized (sLock) { + StatusBarNotification notification = getCurrentlyShownNotificationLocked(context); + if (notification != null && notification.getUser().equals(user) + && notification.getTag().equals(pkg)) { + getSystemServiceSafe(context, NotificationManager.class, user).cancel( + pkg, LOCATION_ACCESS_CHECK_NOTIFICATION_ID); + } + + ArraySet packages = loadAlreadyNotifiedPackagesLocked(context); + packages.remove(new UserPackage(pkg, user)); + safeAlreadyNotifiedPackagesLocked(context, packages); + } + } + + /** + * After a small delay schedule a {@link #addLocationNotificationIfNeeded() check} if we should + * show a notification. + * + *

This is called when location access is granted to an app. In this case it is likely that + * the app will access the location soon. If this happens the notification will appear only a + * little after the user granted the location. + * + * @param context A context to resolve managers + */ + public static void checkLocationAccessSoon(@NonNull Context context) { + JobScheduler jobScheduler = getSystemServiceSafe(context, JobScheduler.class); + + JobInfo.Builder b = (new JobInfo.Builder(LOCATION_ACCESS_CHECK_JOB_ID, + new ComponentName(context, LocationAccessCheck.class))) + .setMinimumLatency(getDelayMillis(context)); + + int scheduleResult = jobScheduler.schedule(b.build()); + if (scheduleResult != RESULT_SUCCESS) { + Log.e(LOG_TAG, "Could not schedule location access check " + scheduleResult); + } + } + + /** + * On boot set up a periodic job that starts {@link #addLocationNotificationIfNeeded() checks}. + */ + public static class SetupPeriodicBackgroundLocationAccessCheck extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + JobScheduler jobScheduler = getSystemServiceSafe(context, JobScheduler.class); + UserManager userManager = getSystemServiceSafe(context, UserManager.class); + + UserHandle user = UserHandle.of(myUserId()); + UserHandle parent = userManager.getProfileParent(user); + if (parent != null && !user.equals(parent)) { + // Profile parent handles child profiles too. + return; + } + + if (jobScheduler.getPendingJob(PERIODIC_LOCATION_ACCESS_CHECK_JOB_ID) == null) { + JobInfo.Builder b = (new JobInfo.Builder(PERIODIC_LOCATION_ACCESS_CHECK_JOB_ID, + new ComponentName(context, LocationAccessCheck.class))) + .setPeriodic(getPeriodicCheckIntervalMillis(context), + getFlexForPeriodicCheckMillis(context)); + + int scheduleResult = jobScheduler.schedule(b.build()); + if (scheduleResult != RESULT_SUCCESS) { + Log.e(LOG_TAG, "Could not schedule periodic location access check " + + scheduleResult); + } + } + } + } + + /** + * A {@link AsyncTask task} that runs {@link #addLocationNotificationIfNeeded()} in the + * background. + */ + private static class AddLocationNotificationIfNeededTask extends AsyncTask { + @Override + protected final Void doInBackground(Object... in) { + LocationAccessCheck service = (LocationAccessCheck) in[0]; + JobParameters params = (JobParameters) in[1]; + + try { + service.addLocationNotificationIfNeeded(); + } catch (InterruptedException e) { + service.jobFinished(params, true); + return null; + } finally { + synchronized (sLock) { + service.mAddLocationNotificationIfNeededTask = null; + } + } + + service.jobFinished(params, false); + return null; + } + } + + /** + * Handle the case where the notification is swiped away without further interaction. + */ + public static class NotificationDeleteHandler extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + String pkg = getStringExtraSafe(intent, EXTRA_PACKAGE_NAME); + UserHandle user = getParcelableExtraSafe(intent, EXTRA_USER); + + markAsNotified(context, pkg, user); + } + } + + /** + * Show the location permission switch when the notification is clicked. + */ + public static class NotificationClickHandler extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + String pkg = getStringExtraSafe(intent, EXTRA_PACKAGE_NAME); + UserHandle user = getParcelableExtraSafe(intent, EXTRA_USER); + + markAsNotified(context, pkg, user); + + Intent manageAppPermission = new Intent(context, AppPermissionActivity.class); + manageAppPermission.addFlags(FLAG_ACTIVITY_NEW_TASK); + manageAppPermission.putExtra(EXTRA_PERMISSION_NAME, ACCESS_FINE_LOCATION); + manageAppPermission.putExtra(EXTRA_PACKAGE_NAME, pkg); + manageAppPermission.putExtra(EXTRA_USER, user); + + context.startActivity(manageAppPermission); + } + } + + /** + * If a package gets removed or the data of the package gets cleared, forget that we showed a + * notification for it. + */ + public static class PackageResetHandler extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + Uri data = Preconditions.checkNotNull(intent.getData()); + UserHandle user = getUserHandleForUid(intent.getIntExtra(EXTRA_UID, 0)); + + if (DEBUG) Log.i(LOG_TAG, "Reset " + data.getSchemeSpecificPart()); + + forgetAboutPackage(context, data.getSchemeSpecificPart(), user); + } + } + + /** + * A immutable class containing a package name and a {@link UserHandle}. + */ + private static final class UserPackage { + public final @NonNull String pkg; + public final @NonNull UserHandle user; + + private UserPackage(@NonNull String pkg, @NonNull UserHandle user) { + this.pkg = pkg; + this.user = user; + } + + /** + * Get {@link PackageInfo} for this user package. + * + * @param context A context used to resolve the info + * + * @return The package info + * + * @throws PackageManager.NameNotFoundException if package/user does not exist + */ + public @NonNull PackageInfo getPackageInfo(@NonNull Context context) + throws PackageManager.NameNotFoundException { + return context.createPackageContextAsUser(pkg, 0, user) + .getPackageManager().getPackageInfo(pkg, GET_PERMISSIONS); + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof UserPackage)) { + return false; + } + + UserPackage userPackage = (UserPackage) o; + return pkg.equals(userPackage.pkg) && user.equals(userPackage.user); + } + + @Override + public int hashCode() { + return Objects.hash(pkg, user); + } + } +} diff --git a/src/com/android/packageinstaller/permission/utils/LocationUtils.java b/src/com/android/packageinstaller/permission/utils/LocationUtils.java index 56491aea8..99c594a73 100644 --- a/src/com/android/packageinstaller/permission/utils/LocationUtils.java +++ b/src/com/android/packageinstaller/permission/utils/LocationUtils.java @@ -56,7 +56,15 @@ public class LocationUtils { && isNetworkLocationProvider(context, packageName); } - private static boolean isNetworkLocationProvider(Context context, String packageName) { + /** + * Check if a package is the location provider. + * + * @param context used to resolve managers + * @param packageName the potential location provider + * + * @return {@code true} iff the package is the location provider + */ + public static boolean isNetworkLocationProvider(Context context, String packageName) { try { return packageName.equals(context.getSystemService(LocationManager.class) .getNetworkProviderPackage()); diff --git a/src/com/android/packageinstaller/permission/utils/Utils.java b/src/com/android/packageinstaller/permission/utils/Utils.java index baf76435b..04fc9c359 100644 --- a/src/com/android/packageinstaller/permission/utils/Utils.java +++ b/src/com/android/packageinstaller/permission/utils/Utils.java @@ -40,6 +40,8 @@ import android.content.pm.ResolveInfo; import android.content.res.Resources; import android.content.res.Resources.Theme; import android.graphics.drawable.Drawable; +import android.os.Parcelable; +import android.os.UserHandle; import android.text.Html; import android.text.TextUtils; import android.util.ArrayMap; @@ -51,6 +53,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.StringRes; import androidx.core.text.BidiFormatter; +import androidx.core.util.Preconditions; import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.model.AppPermissions; @@ -149,6 +152,46 @@ public final class Utils { /* do nothing - hide constructor */ } + /** + * {@code @NonNull} version of {@link Context#getSystemService(Class)} + */ + public static @NonNull M getSystemServiceSafe(@NonNull Context context, Class clazz) { + return Preconditions.checkNotNull(context.getSystemService(clazz), + "Could not resolve " + clazz.getSimpleName()); + } + + /** + * {@code @NonNull} version of {@link Context#getSystemService(Class)} + */ + public static @NonNull M getSystemServiceSafe(@NonNull Context context, Class clazz, + @NonNull UserHandle user) { + try { + return Preconditions.checkNotNull(context.createPackageContextAsUser( + context.getPackageName(), 0, user).getSystemService(clazz), + "Could not resolve " + clazz.getSimpleName()); + } catch (PackageManager.NameNotFoundException neverHappens) { + throw new IllegalStateException(); + } + } + + /** + * {@code @NonNull} version of {@link Intent#getParcelableExtra(String)} + */ + public static @NonNull T getParcelableExtraSafe(@NonNull Intent intent, + @NonNull String name) { + return Preconditions.checkNotNull(intent.getParcelableExtra(name), + "Could not get parcelable extra for " + name); + } + + /** + * {@code @NonNull} version of {@link Intent#getStringExtra(String)} + */ + public static @NonNull String getStringExtraSafe(@NonNull Intent intent, + @NonNull String name) { + return Preconditions.checkNotNull(intent.getStringExtra(name), + "Could not get string extra for " + name); + } + /** * Get permission group a platform permission belongs to. * -- GitLab From 874e664770efa1c01d978dfebb79b86ba4d027e5 Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Mon, 3 Dec 2018 15:48:54 -0800 Subject: [PATCH 159/701] Fix role parser complaining about missing permission. This change fixes role parser complaining about unknown permission in permission sets, by adding special case about isolated storage permissions in validation. Bug: 110557011 Test: manual Change-Id: I2152611fecfe187e0e9bbf942472720297c4a872 --- .../packageinstaller/role/model/Roles.java | 31 ++++++++++++++----- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/src/com/android/packageinstaller/role/model/Roles.java b/src/com/android/packageinstaller/role/model/Roles.java index bc86e6b59..bfeb4b5b7 100644 --- a/src/com/android/packageinstaller/role/model/Roles.java +++ b/src/com/android/packageinstaller/role/model/Roles.java @@ -99,6 +99,17 @@ public class Roles { private static ArrayMap sRoles; private static boolean sIsolatedStorage; + private static final List ISOLATED_STORAGE_PERMISSIONS = new ArrayList<>(); + static { + ISOLATED_STORAGE_PERMISSIONS.add(android.Manifest.permission.READ_MEDIA_AUDIO); + ISOLATED_STORAGE_PERMISSIONS.add(android.Manifest.permission.READ_MEDIA_VIDEO); + ISOLATED_STORAGE_PERMISSIONS.add(android.Manifest.permission.READ_MEDIA_IMAGES); + } + private static final List LEGACY_STORAGE_PERMISSIONS = new ArrayList<>(); + static { + LEGACY_STORAGE_PERMISSIONS.add(android.Manifest.permission.READ_EXTERNAL_STORAGE); + LEGACY_STORAGE_PERMISSIONS.add(android.Manifest.permission.WRITE_EXTERNAL_STORAGE); + } private Roles() {} @@ -125,8 +136,7 @@ public class Roles { // around with permission definitions to return us to pre-Q behavior. // STOPSHIP(b/112545973): remove once feature enabled by default try { - context.getPackageManager() - .getPermissionInfo(android.Manifest.permission.READ_MEDIA_AUDIO, 0); + context.getPackageManager().getPermissionInfo(ISOLATED_STORAGE_PERMISSIONS.get(0), 0); sIsolatedStorage = true; } catch (NameNotFoundException e) { sIsolatedStorage = false; @@ -598,13 +608,9 @@ public class Roles { // around with permission definitions to return us to pre-Q behavior. // STOPSHIP(b/112545973): remove once feature enabled by default if (!sIsolatedStorage) { - boolean removed = false; - removed |= permissions.remove(android.Manifest.permission.READ_MEDIA_AUDIO); - removed |= permissions.remove(android.Manifest.permission.READ_MEDIA_VIDEO); - removed |= permissions.remove(android.Manifest.permission.READ_MEDIA_IMAGES); + boolean removed = permissions.removeAll(ISOLATED_STORAGE_PERMISSIONS); if (removed) { - permissions.add(android.Manifest.permission.READ_EXTERNAL_STORAGE); - permissions.add(android.Manifest.permission.WRITE_EXTERNAL_STORAGE); + permissions.addAll(LEGACY_STORAGE_PERMISSIONS); } } @@ -852,6 +858,15 @@ public class Roles { for (int permissionsIndex = 0; permissionsIndex < permissionsSize; permissionsIndex++) { String permission = permissions.get(permissionsIndex); + // If the storage model feature flag is disabled, we need to fiddle + // around with permission definitions to return us to pre-Q behavior. + // STOPSHIP(b/112545973): remove once feature enabled by default + if (!sIsolatedStorage) { + if (ISOLATED_STORAGE_PERMISSIONS.contains(permission)) { + continue; + } + } + validatePermission(permission, context); } } -- GitLab From e311ed097af36bf69744b38c04b883b1aa8ed1a8 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Fri, 30 Nov 2018 13:47:19 -0800 Subject: [PATCH 160/701] Add permission justifications to AppPermissionFragment. This adds text describing an app's permission justifications to AppPermissionFragment. Bug: 63532550 Bug: 111207567 Test: Open AppPermissionFragment, see text. Test: Manually hardcode different values, see text change. Test: atest android.appsecurity.cts.PermissionsHostTest Change-Id: I7873227e49fd276eb7bc7639e8883c0124d7c73b --- res/layout/app_permission.xml | 53 +++++++ res/values/strings.xml | 39 +++++ res/values/styles.xml | 8 + .../permission/model/AppPermissionGroup.java | 5 +- .../permission/model/Permission.java | 20 ++- .../ui/handheld/AppPermissionFragment.java | 148 ++++++++++++++++++ 6 files changed, 265 insertions(+), 8 deletions(-) diff --git a/res/layout/app_permission.xml b/res/layout/app_permission.xml index 95f109b22..92edfa1aa 100644 --- a/res/layout/app_permission.xml +++ b/res/layout/app_permission.xml @@ -132,6 +132,59 @@ android:layout_height="wrap_content" style="@style/FooterText"/> + + + + + + + + + + + + + + + + + + + + Music app + + The app developer says your data may be: + + + If you don\u2019t like how this app developer is using your data you can deny the permission. + + + Uploaded to cloud + + + Uploaded to cloud when you explicitly allow it + + + Shared with advertisers or businesses + + + Shared with advertisers or businesses when you explicitly allow it + + + Used for monetization + + + Used for monetization when you explicitly allow it + + + Saved and analyzed forever + + + Saved and analyzed for a duration you specify + + + + Saved and analyzed for 1 week + Saved and analyzed for %s weeks + + + + The app developer did not specify how the app uses your data. + diff --git a/res/values/styles.xml b/res/values/styles.xml index 34b71d59f..fb6e77b5c 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -33,4 +33,12 @@ 48dp ?android:attr/textColorSecondary + + diff --git a/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java b/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java index 147cdf415..c4e3ad3e9 100644 --- a/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java +++ b/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java @@ -235,9 +235,8 @@ public final class AppPermissionGroup implements Comparable final int flags = context.getPackageManager().getPermissionFlags( requestedPermission, packageName, userHandle); - Permission permission = new Permission(requestedPermission, - requestedPermissionInfo.backgroundPermission, granted, - appOp, appOpAllowed, flags, requestedPermissionInfo.protectionLevel); + Permission permission = new Permission(requestedPermission, requestedPermissionInfo, + granted, appOp, appOpAllowed, flags); if (requestedPermissionInfo.backgroundPermission != null) { group.mHasPermissionWithBackgroundMode = true; diff --git a/src/com/android/packageinstaller/permission/model/Permission.java b/src/com/android/packageinstaller/permission/model/Permission.java index 2e555f32e..38027dc3a 100644 --- a/src/com/android/packageinstaller/permission/model/Permission.java +++ b/src/com/android/packageinstaller/permission/model/Permission.java @@ -19,6 +19,8 @@ package com.android.packageinstaller.permission.model; import android.content.pm.PackageManager; import android.content.pm.PermissionInfo; +import androidx.annotation.NonNull; + import java.util.ArrayList; /** @@ -27,6 +29,7 @@ import java.util.ArrayList; * @see AppPermissionGroup */ public final class Permission { + private final @NonNull PermissionInfo mPermissionInfo; private final String mName; private final String mBackgroundPermissionName; private final String mAppOp; @@ -39,16 +42,19 @@ public final class Permission { private Permission mBackgroundPermission; private ArrayList mForegroundPermissions; - public Permission(String name, String backgroundPermissionName, boolean granted, - String appOp, boolean appOpAllowed, int flags, int protectionLevel) { + public Permission(String name, @NonNull PermissionInfo permissionInfo, boolean granted, + String appOp, boolean appOpAllowed, int flags) { + mPermissionInfo = permissionInfo; mName = name; - mBackgroundPermissionName = backgroundPermissionName; + mBackgroundPermissionName = permissionInfo.backgroundPermission; mGranted = granted; mAppOp = appOp; mAppOpAllowed = appOpAllowed; mFlags = flags; - mIsEphemeral = (protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTANT) != 0; - mIsRuntimeOnly = (protectionLevel & PermissionInfo.PROTECTION_FLAG_RUNTIME_ONLY) != 0; + mIsEphemeral = + (permissionInfo.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTANT) != 0; + mIsRuntimeOnly = + (permissionInfo.protectionLevel & PermissionInfo.PROTECTION_FLAG_RUNTIME_ONLY) != 0; } /** @@ -72,6 +78,10 @@ public final class Permission { mBackgroundPermission = backgroundPermission; } + public PermissionInfo getPermissionInfo() { + return mPermissionInfo; + } + public String getName() { return mName; } diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java index 8b99cd532..4b7d0dca9 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java @@ -29,9 +29,11 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; +import android.content.pm.UsesPermissionInfo; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.UserHandle; +import android.util.ArraySet; import android.util.Log; import android.view.LayoutInflater; import android.view.MenuItem; @@ -50,6 +52,7 @@ import androidx.fragment.app.Fragment; import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.model.AppPermissionUsage; +import com.android.packageinstaller.permission.model.Permission; import com.android.packageinstaller.permission.utils.IconDrawableFactory; import com.android.packageinstaller.permission.utils.LocationUtils; import com.android.packageinstaller.permission.utils.PackageRemovalMonitor; @@ -59,6 +62,7 @@ import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; import java.lang.annotation.Retention; +import java.util.ArrayList; import java.util.List; /** @@ -191,6 +195,7 @@ public class AppPermissionFragment extends PermissionsFrameFragment { mPermissionDetails = root.requireViewById(R.id.permission_details); updateButtons(); + updateJustification(context, root); return root; } @@ -376,6 +381,149 @@ public class AppPermissionFragment extends PermissionsFrameFragment { } } + private void updateJustification(Context context, ViewGroup root) { + // Collect the names of the permissions of the group. + ArrayList groupPerms = mGroup.getPermissions(); + ArraySet permissions = new ArraySet(groupPerms.size()); + for (int i = 0; i < groupPerms.size(); i++) { + Permission permission = groupPerms.get(i); + if (permission.getPermissionInfo().usageInfoRequired) { + permissions.add(permission.getName()); + } + } + + // If no permissions require usage information, show nothing. + if (permissions.isEmpty()) { + root.requireViewById(R.id.justification_all).setVisibility(View.GONE); + return; + } + + int sentOffDevice = UsesPermissionInfo.USAGE_NO; + int sharedWithThirdParty = UsesPermissionInfo.USAGE_NO; + int usedForMonetization = UsesPermissionInfo.USAGE_NO; + int retention = UsesPermissionInfo.RETENTION_NOT_RETAINED; + int retentionWeeks = -1; + + // Compute the strongest justification by this app. + UsesPermissionInfo[] justifications = mGroup.getApp().usesPermissions; + for (int i = 0; i < justifications.length; i++) { + UsesPermissionInfo justification = justifications[i]; + + // Only consider permissions in this group. + if (!permissions.contains(justification.getPermission())) { + continue; + } + + sentOffDevice = Math.min(sentOffDevice, justification.getDataSentOffDevice()); + sharedWithThirdParty = Math.min(sharedWithThirdParty, + justification.getDataSharedWithThirdParty()); + usedForMonetization = Math.min(usedForMonetization, + justification.getDataUsedForMonetization()); + retention = compareRetentions(retention, justification.getDataRetention()); + if (justification.getDataRetention() == UsesPermissionInfo.RETENTION_SPECIFIED) { + retentionWeeks = Math.max(retentionWeeks, justification.getDataRetentionWeeks()); + } + } + + if (isSystemFixed() || isPolicyFullyFixed()) { + root.requireViewById(R.id.justification_footer).setVisibility(View.GONE); + } + + if (sentOffDevice == UsesPermissionInfo.USAGE_UNDEFINED + || sharedWithThirdParty == UsesPermissionInfo.USAGE_UNDEFINED + || usedForMonetization == UsesPermissionInfo.USAGE_UNDEFINED + || retention == UsesPermissionInfo.RETENTION_UNDEFINED) { + // If at least one permission is undefined, only show the generic undefined string. + root.requireViewById(R.id.justification_entries).setVisibility(View.GONE); + ((TextView) root.requireViewById(R.id.justification_header)).setText( + context.getString(R.string.permission_justification_undefined)); + } else { + // Show/hide or set the text of the various text views. + ((TextView) root.requireViewById(R.id.justification_header)).setText( + context.getString(R.string.permission_justification_header)); + setUsageText(root.requireViewById(R.id.justification_sent_off_device), sentOffDevice, + R.string.permission_justification_data_sent_off_device, + R.string.permission_justification_data_sent_off_device_user_triggered, context); + setUsageText(root.requireViewById(R.id.justification_shared_with_third_party), + sharedWithThirdParty, + R.string.permission_justification_data_shared_with_third_party, + R.string.permission_justification_data_shared_with_third_party_user_triggered, + context); + setUsageText(root.requireViewById(R.id.justification_used_for_monetization), + usedForMonetization, + R.string.permission_justification_data_used_for_monetization, + R.string.permission_justification_data_used_for_monetization_user_triggered, + context); + TextView retentionTextView = root.requireViewById(R.id.justification_retention); + if (retention == UsesPermissionInfo.RETENTION_NOT_RETAINED) { + retentionTextView.setVisibility(View.GONE); + } else if (retention == UsesPermissionInfo.RETENTION_USER_SELECTED) { + retentionTextView.setText(context.getString( + R.string.permission_justification_data_retention_user_selected)); + } else if (retention == UsesPermissionInfo.RETENTION_SPECIFIED) { + retentionTextView.setText(context.getResources().getQuantityString( + R.plurals.permission_justification_data_retention_specified, retentionWeeks, + retentionWeeks)); + } else { + retentionTextView.setText(context.getString( + R.string.permission_justification_data_retention_unlimited)); + } + } + } + + /** + * Compare two UsesPermissionInfo.Retention values and return the stronger. + * + * @param r1 a Retention value + * @param r2 another Retention value + * @return the stronger of the two values + */ + private static int compareRetentions(int r1, int r2) { + if (r1 == UsesPermissionInfo.RETENTION_UNDEFINED + || r2 == UsesPermissionInfo.RETENTION_UNDEFINED) { + return UsesPermissionInfo.RETENTION_UNDEFINED; + } + if (r1 == UsesPermissionInfo.RETENTION_UNLIMITED + || r2 == UsesPermissionInfo.RETENTION_UNLIMITED) { + return UsesPermissionInfo.RETENTION_UNLIMITED; + } + if (r1 == UsesPermissionInfo.RETENTION_SPECIFIED + || r2 == UsesPermissionInfo.RETENTION_SPECIFIED) { + return UsesPermissionInfo.RETENTION_SPECIFIED; + } + if (r1 == UsesPermissionInfo.RETENTION_USER_SELECTED + || r2 == UsesPermissionInfo.RETENTION_USER_SELECTED) { + return UsesPermissionInfo.RETENTION_USER_SELECTED; + } + if (r1 == UsesPermissionInfo.RETENTION_NOT_RETAINED + || r2 == UsesPermissionInfo.RETENTION_NOT_RETAINED) { + return UsesPermissionInfo.RETENTION_NOT_RETAINED; + } + Log.w(LOG_TAG, "Invalid retention: " + r1 + ", " + r2); + return UsesPermissionInfo.RETENTION_UNDEFINED; + } + + /** + * Set the text of the given view to one of the given values or hide it if necessary. + * + * @param textView the TextView to change + * @param value the value that controls which text to use + * @param yesStrId the resId of the string to use if the usage is allowed + * @param userTriggeredStrId the resId of the string to use if the usage is allowed on user- + * triggered actions. + * @param context the context + */ + private void setUsageText(TextView textView, int value, int yesStrId, int userTriggeredStrId, + Context context) { + if (value == UsesPermissionInfo.USAGE_NO) { + textView.setVisibility(View.GONE); + } else if (value == UsesPermissionInfo.USAGE_USER_TRIGGERED) { + textView.setText(context.getString(userTriggeredStrId)); + } else { + textView.setText(context.getString(yesStrId)); + } + } + /** * Set the given button as the only checked button in the radio group. * -- GitLab From e46385415225135901f38e4648a03a4dd783123a Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Tue, 4 Dec 2018 10:09:55 -0800 Subject: [PATCH 161/701] Correctly annotate null-ness in RuntimePermissionPresenterServiceImpl Test: Built Change-Id: I16c7376a80471611ebd6df5b8b051aee5aa1ab95 --- .../service/RuntimePermissionPresenterServiceImpl.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/com/android/packageinstaller/permission/service/RuntimePermissionPresenterServiceImpl.java b/src/com/android/packageinstaller/permission/service/RuntimePermissionPresenterServiceImpl.java index 774d8a228..3f78a34ec 100644 --- a/src/com/android/packageinstaller/permission/service/RuntimePermissionPresenterServiceImpl.java +++ b/src/com/android/packageinstaller/permission/service/RuntimePermissionPresenterServiceImpl.java @@ -22,6 +22,8 @@ import android.content.pm.permission.RuntimePermissionPresentationInfo; import android.permissionpresenterservice.RuntimePermissionPresenterService; import android.util.Log; +import androidx.annotation.NonNull; + import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.model.AppPermissions; import com.android.packageinstaller.permission.utils.Utils; @@ -36,7 +38,8 @@ public final class RuntimePermissionPresenterServiceImpl extends RuntimePermissi private static final String LOG_TAG = "PermissionPresenter"; @Override - public List onGetAppPermissions(String packageName) { + public List onGetAppPermissions( + @NonNull String packageName) { final PackageInfo packageInfo; try { packageInfo = getPackageManager().getPackageInfo(packageName, @@ -64,7 +67,8 @@ public final class RuntimePermissionPresenterServiceImpl extends RuntimePermissi } @Override - public void onRevokeRuntimePermission(String packageName, String permissionName) { + public void onRevokeRuntimePermission(@NonNull String packageName, + @NonNull String permissionName) { try { final PackageInfo packageInfo = getPackageManager().getPackageInfo(packageName, PackageManager.GET_PERMISSIONS); -- GitLab From a8af17fafc950d0c29d6d5b99cce17b2c9145bca Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Mon, 3 Dec 2018 15:52:26 -0800 Subject: [PATCH 162/701] Fix request role dialog UI not dismissing. This change fixes the request role dialog UI so that it can be dismissed correctly, by overriding DialogFragment.onDismiss() which should be used instead of setOnDismissListener(). It also fixes the theme so that there is not title panel under the dialog. Bug: 110557011 Test: manual Change-Id: I015c4eb3a2be577863f46b9962b16661aae81f30 --- res/values/themes.xml | 4 +-- .../role/ui/RequestRoleFragment.java | 31 ++++++++++++++----- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/res/values/themes.xml b/res/values/themes.xml index a7bfa758f..c583354f7 100644 --- a/res/values/themes.xml +++ b/res/values/themes.xml @@ -43,7 +43,7 @@ parent="@android:style/Theme.DeviceDefault.Settings"> - diff --git a/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java b/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java index 955b01d6a..25e17377a 100644 --- a/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java +++ b/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java @@ -21,6 +21,7 @@ import android.app.AlertDialog; import android.app.Dialog; import android.app.role.RoleManager; import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.os.Bundle; @@ -53,6 +54,7 @@ public class RequestRoleFragment extends DialogFragment { private RequestRoleViewModel mViewModel; + @Nullable private PackageRemovalMonitor mPackageRemovalMonitor; /** @@ -127,11 +129,6 @@ public class RequestRoleFragment extends DialogFragment { // Set the positive button listener later to avoid the automatic dismiss behavior. .setPositiveButton(android.R.string.ok, null) .setNegativeButton(android.R.string.cancel, null) - .setOnDismissListener(dialog2 -> { - Log.i(LOG_TAG, "Dialog dismissed, role: " + mRoleName + ", package: " - + mPackageName); - finish(); - }) .create(); dialog.setOnShowListener(dialog2 -> dialog.getButton(Dialog.BUTTON_POSITIVE) .setOnClickListener(view -> addRoleHolder())); @@ -150,7 +147,14 @@ public class RequestRoleFragment extends DialogFragment { public void onStart() { super.onStart(); - mPackageRemovalMonitor = new PackageRemovalMonitor(requireContext(), mPackageName) { + Context context = requireContext(); + if (PackageUtils.getApplicationInfo(mPackageName, context) == null) { + Log.w(LOG_TAG, "Unknown application: " + mPackageName); + finish(); + return; + } + + mPackageRemovalMonitor = new PackageRemovalMonitor(context, mPackageName) { @Override protected void onPackageRemoved() { Log.w(LOG_TAG, "Application is uninstalled, role: " + mRoleName + ", package: " @@ -165,8 +169,19 @@ public class RequestRoleFragment extends DialogFragment { public void onStop() { super.onStop(); - mPackageRemovalMonitor.unregister(); - mPackageRemovalMonitor = null; + if (mPackageRemovalMonitor != null) { + mPackageRemovalMonitor.unregister(); + mPackageRemovalMonitor = null; + } + } + + @Override + public void onDismiss(DialogInterface dialog) { + super.onDismiss(dialog); + + Log.i(LOG_TAG, "Dialog dismissed, role: " + mRoleName + ", package: " + + mPackageName); + finish(); } private void onRequestRoleStateChanged(int state) { -- GitLab From 7cec48b064e40bed93026728c2aae53f3d9d77cd Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Mon, 19 Nov 2018 12:02:16 -0800 Subject: [PATCH 163/701] Add test for RoleManager. This change adds RoleManagerTest to test mapping. Bug: 110557011 Test: atest android.app.role.cts.RoleManagerTest Change-Id: I6f1c532bbdafa763a7a1a62339c76a1fb64189a3 --- TEST_MAPPING | 3 +++ 1 file changed, 3 insertions(+) diff --git a/TEST_MAPPING b/TEST_MAPPING index 83f1155fd..7a7f4b196 100644 --- a/TEST_MAPPING +++ b/TEST_MAPPING @@ -7,6 +7,9 @@ "include-filter": "android.permission.cts.BackgroundPermissionsTest" } ] + }, + { + "name": "CtsRoleTestCases" } ] } -- GitLab From 780e90dbbc52dddb9734e7863d0c412cc92ca65f Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Thu, 29 Nov 2018 14:09:24 -0800 Subject: [PATCH 164/701] Add activity to manage the list of default apps. This change adds the activity to manage the list of default apps. Bug: 110557011 Test: manual Change-Id: I6d21c0296b3518ef478d189135c1b2b53cac47d3 --- AndroidManifest.xml | 13 ++ res/layout/settings.xml | 52 +++++++ res/menu/settings.xml | 26 ++++ res/values/strings.xml | 10 ++ .../ui/handheld/PermissionsFrameFragment.java | 32 +---- .../permission/utils/Utils.java | 28 ++++ .../role/ui/AppIconPreference.java | 116 +++++++++++++++ .../role/ui/AsyncTaskLiveData.java | 40 ++++++ .../role/ui/DefaultAppListActivity.java | 40 ++++++ .../role/ui/DefaultAppListFragment.java | 136 ++++++++++++++++++ .../role/ui/RequestRoleFragment.java | 6 +- .../packageinstaller/role/ui/RoleItem.java | 58 ++++++++ .../role/ui/RoleListLiveData.java | 90 ++++++++++++ .../role/ui/RoleListViewModel.java | 67 +++++++++ .../role/ui/SettingsFragment.java | 132 +++++++++++++++++ .../packageinstaller/role/utils/UiUtils.java | 82 +++++++++++ 16 files changed, 895 insertions(+), 33 deletions(-) create mode 100644 res/layout/settings.xml create mode 100644 res/menu/settings.xml create mode 100644 src/com/android/packageinstaller/role/ui/AppIconPreference.java create mode 100644 src/com/android/packageinstaller/role/ui/AsyncTaskLiveData.java create mode 100644 src/com/android/packageinstaller/role/ui/DefaultAppListActivity.java create mode 100644 src/com/android/packageinstaller/role/ui/DefaultAppListFragment.java create mode 100644 src/com/android/packageinstaller/role/ui/RoleItem.java create mode 100644 src/com/android/packageinstaller/role/ui/RoleListLiveData.java create mode 100644 src/com/android/packageinstaller/role/ui/RoleListViewModel.java create mode 100644 src/com/android/packageinstaller/role/ui/SettingsFragment.java create mode 100644 src/com/android/packageinstaller/role/utils/UiUtils.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index aace6dfc8..a3bcda693 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -124,6 +124,19 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/menu/settings.xml b/res/menu/settings.xml new file mode 100644 index 000000000..74c0e3f93 --- /dev/null +++ b/res/menu/settings.xml @@ -0,0 +1,26 @@ + + + + +

+ + + diff --git a/res/values/strings.xml b/res/values/strings.xml index 70ee60594..c458a418f 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -341,6 +341,16 @@ This app can always access your location. Tap to change. + + Default apps + + + + + + + No default apps + diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionsFrameFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionsFrameFragment.java index c81d1399c..af4b21be0 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionsFrameFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionsFrameFragment.java @@ -16,17 +16,10 @@ package com.android.packageinstaller.permission.ui.handheld; -import static android.provider.Settings.ACTION_APP_SEARCH_SETTINGS; -import static android.view.MenuItem.SHOW_AS_ACTION_ALWAYS; - -import android.content.ActivityNotFoundException; -import android.content.Intent; import android.os.Bundle; -import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; -import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.view.animation.Animation; @@ -37,12 +30,12 @@ import android.widget.TextView; import androidx.preference.PreferenceFragmentCompat; import androidx.recyclerview.widget.RecyclerView; +import com.android.packageinstaller.permission.utils.Utils; import com.android.permissioncontroller.R; public abstract class PermissionsFrameFragment extends PreferenceFragmentCompat { private static final String LOG_TAG = PermissionsFrameFragment.class.getSimpleName(); - private static final int MENU_SEARCH_SETTINGS = Menu.FIRST; static final int MENU_ALL_PERMS = Menu.FIRST + 1; static final int MENU_SHOW_SYSTEM = Menu.FIRST + 2; static final int MENU_HIDE_SYSTEM = Menu.FIRST + 3; @@ -66,28 +59,7 @@ public abstract class PermissionsFrameFragment extends PreferenceFragmentCompat public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { super.onCreateOptionsMenu(menu, inflater); - if (getContext().getPackageManager().resolveActivity(new Intent(ACTION_APP_SEARCH_SETTINGS), - 0) != null) { - MenuItem searchItem = menu.add(Menu.NONE, MENU_SEARCH_SETTINGS, Menu.NONE, - R.string.search_menu); - searchItem.setIcon(R.drawable.ic_search_24dp); - searchItem.setShowAsAction(SHOW_AS_ACTION_ALWAYS); - } - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case MENU_SEARCH_SETTINGS: - try { - getActivity().startActivity(new Intent(ACTION_APP_SEARCH_SETTINGS)); - } catch (ActivityNotFoundException e) { - Log.e(LOG_TAG, "Cannot search settings", e); - } - break; - } - - return super.onOptionsItemSelected(item); + Utils.prepareSearchMenuItem(menu, requireContext()); } @Override diff --git a/src/com/android/packageinstaller/permission/utils/Utils.java b/src/com/android/packageinstaller/permission/utils/Utils.java index 85be02fd3..e4caec32a 100644 --- a/src/com/android/packageinstaller/permission/utils/Utils.java +++ b/src/com/android/packageinstaller/permission/utils/Utils.java @@ -31,6 +31,7 @@ import static android.Manifest.permission_group.SMS; import static android.Manifest.permission_group.STORAGE; import android.Manifest; +import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; @@ -42,12 +43,15 @@ import android.content.res.Resources.Theme; import android.graphics.drawable.Drawable; import android.os.Parcelable; import android.os.UserHandle; +import android.provider.Settings; import android.text.Html; import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Log; import android.util.TypedValue; +import android.view.Menu; +import android.view.MenuItem; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -439,4 +443,28 @@ public final class Utils { long days = hours / 24; return context.getResources().getQuantityString(R.plurals.days, (int) days, days); } + + /** + * Add a menu item for searching Settings, if there is an activity handling the action. + * + * @param menu the menu to add the menu item into + * @param context the context for checking whether there is an activity handling the action + */ + public static void prepareSearchMenuItem(@NonNull Menu menu, @NonNull Context context) { + Intent intent = new Intent(Settings.ACTION_APP_SEARCH_SETTINGS); + if (context.getPackageManager().resolveActivity(intent, 0) == null) { + return; + } + MenuItem searchItem = menu.add(Menu.NONE, Menu.NONE, Menu.NONE, R.string.search_menu); + searchItem.setIcon(R.drawable.ic_search_24dp); + searchItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); + searchItem.setOnMenuItemClickListener(item -> { + try { + context.startActivity(intent); + } catch (ActivityNotFoundException e) { + Log.e(LOG_TAG, "Cannot start activity to search settings", e); + } + return true; + }); + } } diff --git a/src/com/android/packageinstaller/role/ui/AppIconPreference.java b/src/com/android/packageinstaller/role/ui/AppIconPreference.java new file mode 100644 index 000000000..244f4c37c --- /dev/null +++ b/src/com/android/packageinstaller/role/ui/AppIconPreference.java @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.packageinstaller.role.ui; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.AttrRes; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.Px; +import androidx.annotation.StyleRes; +import androidx.preference.Preference; +import androidx.preference.PreferenceViewHolder; + +import com.android.permissioncontroller.R; + +/** + * {@link Preference} with its icon view set to a fixed size for app icons. + */ +public class AppIconPreference extends Preference { + + private Mixin mMixin; + + public AppIconPreference(@NonNull Context context, @Nullable AttributeSet attrs, + @AttrRes int defStyleAttr, @StyleRes int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + + init(); + } + + public AppIconPreference(@NonNull Context context, @Nullable AttributeSet attrs, + @AttrRes int defStyleAttr) { + super(context, attrs, defStyleAttr); + + init(); + } + + public AppIconPreference(@NonNull Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + + init(); + } + + public AppIconPreference(@NonNull Context context) { + super(context); + + init(); + } + + private void init() { + mMixin = new Mixin(getContext()); + } + + @Override + public void onBindViewHolder(@NonNull PreferenceViewHolder holder) { + super.onBindViewHolder(holder); + + mMixin.onBindViewHolder(holder); + } + + /** + * Mixin for implementation of {@link AppIconPreference}. + */ + public static class Mixin { + + @Px + private int mIconSize; + + public Mixin(@NonNull Context context) { + mIconSize = context.getResources().getDimensionPixelSize( + R.dimen.secondary_app_icon_size); + } + + /** + * Binds the view holder so that its icon view is set to a fixed size for app icons. + * + * @param holder the view holder passed in by {@link Preference#onBindViewHolder( + * PreferenceViewHolder)} + * + * @see Preference#onBindViewHolder(PreferenceViewHolder) + */ + public void onBindViewHolder(@NonNull PreferenceViewHolder holder) { + View iconView = holder.findViewById(android.R.id.icon); + ViewGroup.LayoutParams layoutParams = iconView.getLayoutParams(); + boolean changed = false; + if (layoutParams.width != mIconSize) { + layoutParams.width = mIconSize; + changed = true; + } + if (layoutParams.height != mIconSize) { + layoutParams.height = mIconSize; + changed = true; + } + if (changed) { + iconView.requestLayout(); + } + } + } +} diff --git a/src/com/android/packageinstaller/role/ui/AsyncTaskLiveData.java b/src/com/android/packageinstaller/role/ui/AsyncTaskLiveData.java new file mode 100644 index 000000000..970bfd346 --- /dev/null +++ b/src/com/android/packageinstaller/role/ui/AsyncTaskLiveData.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.packageinstaller.role.ui; + +import android.os.AsyncTask; + +import androidx.annotation.WorkerThread; +import androidx.lifecycle.LiveData; + +/** + * {@link LiveData} that uses {@link AsyncTask} to load value on a background thread. + * + * @param type of the value + */ +public abstract class AsyncTaskLiveData extends LiveData { + + /** + * Load the value on a background thread. The value will be reloaded even if already loaded. + */ + public void loadValue() { + AsyncTask.execute(() -> postValue(loadValueInBackground())); + } + + @WorkerThread + protected abstract T loadValueInBackground(); +} diff --git a/src/com/android/packageinstaller/role/ui/DefaultAppListActivity.java b/src/com/android/packageinstaller/role/ui/DefaultAppListActivity.java new file mode 100644 index 000000000..66bee250c --- /dev/null +++ b/src/com/android/packageinstaller/role/ui/DefaultAppListActivity.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.packageinstaller.role.ui; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentActivity; + +/** + * Activity for the list of default apps. + */ +public class DefaultAppListActivity extends FragmentActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + if (savedInstanceState == null) { + DefaultAppListFragment fragment = DefaultAppListFragment.newInstance(); + getSupportFragmentManager().beginTransaction() + .add(android.R.id.content, fragment) + .commit(); + } + } +} diff --git a/src/com/android/packageinstaller/role/ui/DefaultAppListFragment.java b/src/com/android/packageinstaller/role/ui/DefaultAppListFragment.java new file mode 100644 index 000000000..536252d6c --- /dev/null +++ b/src/com/android/packageinstaller/role/ui/DefaultAppListFragment.java @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.packageinstaller.role.ui; + +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.os.Bundle; +import android.os.UserHandle; +import android.util.ArrayMap; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.StringRes; +import androidx.lifecycle.ViewModelProviders; +import androidx.preference.Preference; +import androidx.preference.PreferenceManager; +import androidx.preference.PreferenceScreen; + +import com.android.packageinstaller.permission.utils.IconDrawableFactory; +import com.android.packageinstaller.permission.utils.Utils; +import com.android.packageinstaller.role.model.Role; +import com.android.permissioncontroller.R; + +import java.util.List; + +/** + * Fragment for the list of default apps. + */ +public class DefaultAppListFragment extends SettingsFragment + implements Preference.OnPreferenceClickListener { + + private static final String LOG_TAG = DefaultAppListFragment.class.getSimpleName(); + + private RoleListViewModel mViewModel; + + /** + * Create a new instance of this fragment. + * + * @return a new instance of this fragment + */ + @NonNull + public static DefaultAppListFragment newInstance() { + return new DefaultAppListFragment(); + } + + @Override + public void onActivityCreated(@Nullable Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + mViewModel = ViewModelProviders.of(this, new RoleListViewModel.Factory(true, + requireActivity().getApplication())).get(RoleListViewModel.class); + mViewModel.getLiveData().observe(this, this::onRoleListChanged); + } + + @Override + @StringRes + protected int getEmptyTextResource() { + return R.string.no_default_apps; + } + + @Override + protected int getHelpUriResource() { + return R.string.help_uri_default_apps; + } + + private void onRoleListChanged(@NonNull List roleItems) { + PreferenceManager preferenceManager = getPreferenceManager(); + Context context = preferenceManager.getContext(); + + PreferenceScreen preferenceScreen = getPreferenceScreen(); + ArrayMap oldPreferences = new ArrayMap<>(); + if (preferenceScreen == null) { + preferenceScreen = preferenceManager.createPreferenceScreen(context); + setPreferenceScreen(preferenceScreen); + } else { + for (int i = preferenceScreen.getPreferenceCount() - 1; i >= 0; --i) { + Preference preference = preferenceScreen.getPreference(i); + + preferenceScreen.removePreference(preference); + oldPreferences.put(preference.getKey(), preference); + } + } + + int roleItemsSize = roleItems.size(); + for (int roleItemsIndex = 0; roleItemsIndex < roleItemsSize; roleItemsIndex++) { + RoleItem roleItem = roleItems.get(roleItemsIndex); + + List holderApplicationInfos = roleItem.getHolderApplicationInfos(); + if (holderApplicationInfos.isEmpty()) { + // TODO: Handle Assistant which is visible even without holder. + continue; + } + + Role role = roleItem.getRole(); + Preference preference = oldPreferences.get(role.getName()); + if (preference == null) { + preference = new AppIconPreference(context); + preference.setKey(role.getName()); + preference.setIconSpaceReserved(true); + preference.setTitle(role.getLabelResource()); + preference.setPersistent(false); + preference.setOnPreferenceClickListener(this); + } + + ApplicationInfo holderApplicationInfo = holderApplicationInfos.get(0); + preference.setIcon(IconDrawableFactory.getBadgedIcon(context, holderApplicationInfo, + UserHandle.getUserHandleForUid(holderApplicationInfo.uid))); + preference.setSummary(Utils.getAppLabel(holderApplicationInfo, context)); + + // TODO: Ordering? + preferenceScreen.addPreference(preference); + } + + updateState(); + } + + @Override + public boolean onPreferenceClick(@NonNull Preference preference) { + // TODO + return true; + } +} diff --git a/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java b/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java index 955b01d6a..cac4bc533 100644 --- a/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java +++ b/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java @@ -65,12 +65,12 @@ public class RequestRoleFragment extends DialogFragment { */ public static RequestRoleFragment newInstance(@NonNull String roleName, @NonNull String packageName) { - RequestRoleFragment instance = new RequestRoleFragment(); + RequestRoleFragment fragment = new RequestRoleFragment(); Bundle arguments = new Bundle(); arguments.putString(RoleManager.EXTRA_REQUEST_ROLE_NAME, roleName); arguments.putString(Intent.EXTRA_PACKAGE_NAME, packageName); - instance.setArguments(arguments); - return instance; + fragment.setArguments(arguments); + return fragment; } @Override diff --git a/src/com/android/packageinstaller/role/ui/RoleItem.java b/src/com/android/packageinstaller/role/ui/RoleItem.java new file mode 100644 index 000000000..01118e89d --- /dev/null +++ b/src/com/android/packageinstaller/role/ui/RoleItem.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.packageinstaller.role.ui; + +import android.content.pm.ApplicationInfo; + +import androidx.annotation.NonNull; + +import com.android.packageinstaller.role.model.Role; + +import java.util.List; + +/** + * Information about a role to be displayed in a list of roles. + */ +public class RoleItem { + + /** + * The {@link Role} for this role. + */ + @NonNull + private final Role mRole; + + /** + * The list of {@link ApplicationInfo} of applications holding this role. + */ + @NonNull + private final List mHolderApplicationInfos; + + public RoleItem(@NonNull Role role, @NonNull List holderApplicationInfos) { + mRole = role; + mHolderApplicationInfos = holderApplicationInfos; + } + + @NonNull + public Role getRole() { + return mRole; + } + + @NonNull + public List getHolderApplicationInfos() { + return mHolderApplicationInfos; + } +} diff --git a/src/com/android/packageinstaller/role/ui/RoleListLiveData.java b/src/com/android/packageinstaller/role/ui/RoleListLiveData.java new file mode 100644 index 000000000..af2275391 --- /dev/null +++ b/src/com/android/packageinstaller/role/ui/RoleListLiveData.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.packageinstaller.role.ui; + +import android.app.role.RoleManager; +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.util.ArrayMap; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.WorkerThread; +import androidx.lifecycle.LiveData; + +import com.android.packageinstaller.role.model.Role; +import com.android.packageinstaller.role.model.Roles; +import com.android.packageinstaller.role.utils.PackageUtils; + +import java.util.ArrayList; +import java.util.List; + +/** + * {@link LiveData} for a list of roles. + */ +public class RoleListLiveData extends AsyncTaskLiveData> { + + private static final String LOG_TAG = RoleListLiveData.class.getSimpleName(); + + private final boolean mExclusive; + private final Context mContext; + + public RoleListLiveData(boolean exclusive, @NonNull Context context) { + mExclusive = exclusive; + mContext = context; + + loadValue(); + } + + @Override + @WorkerThread + protected List loadValueInBackground() { + ArrayMap roles = Roles.getRoles(mContext); + + List roleItems = new ArrayList<>(); + RoleManager roleManager = mContext.getSystemService(RoleManager.class); + int rolesSize = roles.size(); + for (int rolesIndex = 0; rolesIndex < rolesSize; rolesIndex++) { + Role role = roles.valueAt(rolesIndex); + + if (role.isExclusive() != mExclusive) { + continue; + } + + List holderApplicationInfos = new ArrayList<>(); + List holderPackageNames = roleManager.getRoleHolders(role.getName()); + int holderPackageNamesSize = holderPackageNames.size(); + for (int holderPackageNamesIndex = 0; holderPackageNamesIndex < holderPackageNamesSize; + holderPackageNamesIndex++) { + String holderPackageName = holderPackageNames.get(holderPackageNamesIndex); + + ApplicationInfo holderApplicationInfo = PackageUtils.getApplicationInfo( + holderPackageName, mContext); + if (holderApplicationInfo == null) { + Log.w(LOG_TAG, "Cannot get ApplicationInfo for application, skipping: " + + holderPackageName); + continue; + } + holderApplicationInfos.add(holderApplicationInfo); + } + + roleItems.add(new RoleItem(role, holderApplicationInfos)); + } + + return roleItems; + } +} diff --git a/src/com/android/packageinstaller/role/ui/RoleListViewModel.java b/src/com/android/packageinstaller/role/ui/RoleListViewModel.java new file mode 100644 index 000000000..de29928de --- /dev/null +++ b/src/com/android/packageinstaller/role/ui/RoleListViewModel.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.packageinstaller.role.ui; + +import android.app.Application; + +import androidx.annotation.NonNull; +import androidx.lifecycle.AndroidViewModel; +import androidx.lifecycle.ViewModel; +import androidx.lifecycle.ViewModelProvider; + +/** + * {@link ViewModel} for a list of roles. + */ +public class RoleListViewModel extends AndroidViewModel { + + @NonNull + private final RoleListLiveData mLiveData; + + public RoleListViewModel(boolean exclusive, @NonNull Application application) { + super(application); + + mLiveData = new RoleListLiveData(exclusive, application); + } + + @NonNull + public RoleListLiveData getLiveData() { + return mLiveData; + } + + /** + * {@link ViewModelProvider.Factory} for {@link RoleListViewModel}. + */ + public static class Factory implements ViewModelProvider.Factory { + + private boolean mExclusive; + + @NonNull + private Application mApplication; + + public Factory(boolean exclusive, @NonNull Application application) { + mExclusive = exclusive; + mApplication = application; + } + + @NonNull + @Override + public T create(@NonNull Class modelClass) { + //noinspection unchecked + return (T) new RoleListViewModel(mExclusive, mApplication); + } + } +} diff --git a/src/com/android/packageinstaller/role/ui/SettingsFragment.java b/src/com/android/packageinstaller/role/ui/SettingsFragment.java new file mode 100644 index 000000000..c75bd045f --- /dev/null +++ b/src/com/android/packageinstaller/role/ui/SettingsFragment.java @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.packageinstaller.role.ui; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.widget.FrameLayout; +import android.widget.LinearLayout; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.StringRes; +import androidx.preference.PreferenceFragmentCompat; +import androidx.preference.PreferenceScreen; + +import com.android.packageinstaller.permission.utils.Utils; +import com.android.packageinstaller.role.utils.UiUtils; +import com.android.permissioncontroller.R; +import com.android.settingslib.HelpUtils; + +/** + * Base class for settings fragments. + */ +public abstract class SettingsFragment extends PreferenceFragmentCompat { + + private static final String LOG_TAG = SettingsFragment.class.getSimpleName(); + + private FrameLayout mContentLayout; + private LinearLayout mPreferenceLayout; + private View mLoadingView; + private TextView mEmptyText; + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setHasOptionsMenu(true); + } + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + mContentLayout = (FrameLayout) inflater.inflate(R.layout.settings, container, false); + mPreferenceLayout = (LinearLayout) super.onCreateView(inflater, container, + savedInstanceState); + mContentLayout.addView(mPreferenceLayout); + return mContentLayout; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + mLoadingView = mContentLayout.findViewById(R.id.loading); + mEmptyText = mContentLayout.findViewById(R.id.empty); + } + + @Override + public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable String rootKey) { + // We'll manually add preferences later. + } + + @Override + public void onActivityCreated(@Nullable Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + requireActivity().getActionBar().setDisplayHomeAsUpEnabled(true); + + mEmptyText.setText(getEmptyTextResource()); + + updateState(); + } + + @StringRes + protected abstract int getEmptyTextResource(); + + @Override + public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { + super.onCreateOptionsMenu(menu, inflater); + + Utils.prepareSearchMenuItem(menu, requireContext()); + int helpUriResource = getHelpUriResource(); + if (helpUriResource != 0) { + HelpUtils.prepareHelpMenuItem(requireActivity(), menu, helpUriResource, + getClass().getName()); + } + } + + @StringRes + protected int getHelpUriResource() { + return 0; + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + requireActivity().finish(); + return true; + default: + return super.onOptionsItemSelected(item); + } + } + + protected void updateState() { + PreferenceScreen preferenceScreen = getPreferenceScreen(); + boolean isLoading = preferenceScreen == null; + UiUtils.setViewShown(mLoadingView, isLoading); + boolean isEmpty = preferenceScreen != null && preferenceScreen.getPreferenceCount() == 0; + UiUtils.setViewShown(mEmptyText, isEmpty); + } +} diff --git a/src/com/android/packageinstaller/role/utils/UiUtils.java b/src/com/android/packageinstaller/role/utils/UiUtils.java new file mode 100644 index 000000000..ded3e7fc9 --- /dev/null +++ b/src/com/android/packageinstaller/role/utils/UiUtils.java @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.packageinstaller.role.utils; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.view.View; +import android.view.animation.AnimationUtils; +import android.view.animation.Interpolator; + +import androidx.annotation.NonNull; + +/** + * Utility methods about UI. + */ +public class UiUtils { + + private UiUtils() {} + + /** + * Set whether a view is shown. + * + * @param view the view to be set to shown or not + * @param shown whether the view should be shown + */ + public static void setViewShown(@NonNull View view, boolean shown) { + if (shown && view.getVisibility() == View.VISIBLE && view.getAlpha() == 1) { + // This cancels any on-going animation. + view.animate() + .alpha(1) + .setDuration(0); + return; + } else if (!shown && (view.getVisibility() != View.VISIBLE || view.getAlpha() == 0)) { + // This cancels any on-going animation. + view.animate() + .alpha(0) + .setDuration(0); + view.setVisibility(View.INVISIBLE); + return; + } + if (shown && view.getVisibility() != View.VISIBLE) { + view.setAlpha(0); + view.setVisibility(View.VISIBLE); + } + int duration = view.getResources().getInteger(android.R.integer.config_mediumAnimTime); + Interpolator interpolator = AnimationUtils.loadInterpolator(view.getContext(), shown + ? android.R.interpolator.fast_out_slow_in + : android.R.interpolator.fast_out_linear_in); + view.animate() + .alpha(shown ? 1 : 0) + .setDuration(duration) + .setInterpolator(interpolator) + // Always update the listener or the view will try to reuse the previous one. + .setListener(shown ? null : new AnimatorListenerAdapter() { + private boolean mCanceled = false; + @Override + public void onAnimationCancel(@NonNull Animator animator) { + mCanceled = true; + } + @Override + public void onAnimationEnd(@NonNull Animator animator) { + if (!mCanceled) { + view.setVisibility(View.INVISIBLE); + } + } + }); + } +} -- GitLab From 5b70c8759d1fe7f4cee2e2b74e46a520d838d4a7 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Wed, 21 Nov 2018 08:07:09 -0800 Subject: [PATCH 165/701] Have most uses of PermissionPreference go to AppPermissionFragment. Part of the Permissions Hub redesign modifies the existing AppPermissionsFragment and PermissionsAppFragment screens to contain links to the new AppPermissionFragment instead of the inlined toggles of PermissionPreference. This implements that change. In addition, I added the subtitle for individually-controlled preferences to AppPermissionFragment and updated to the latest mocks, which show the most recent usage in the subtitle in AppPermissionsFragment. Bug: 63532550 Test: Open both fragments, change a permission, verify that the preference is moved to the proper segment. Change-Id: I7001e76532426f58581ba7000846117d07cff043 --- res/values/strings.xml | 12 ++ res/xml/allowed_denied.xml | 28 ++++ .../permission/model/PermissionApps.java | 36 +---- .../ui/handheld/AppPermissionFragment.java | 127 ++++++++++++----- .../handheld/AppPermissionUsageFragment.java | 11 +- .../ui/handheld/AppPermissionsFragment.java | 83 ++++-------- .../ui/handheld/PermissionAppsFragment.java | 128 +++++++----------- .../ui/handheld/PermissionUsageFragment.java | 13 +- .../handheld/PermissionUsagePreference.java | 22 +-- .../permission/utils/SafetyNetLogger.java | 11 ++ .../permission/utils/Utils.java | 78 ++++++++++- 11 files changed, 320 insertions(+), 229 deletions(-) create mode 100644 res/xml/allowed_denied.xml diff --git a/res/values/strings.xml b/res/values/strings.xml index 7badf87e9..10d0d07b1 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -294,9 +294,21 @@ %1$s accessed your %2$s %3$s ago. + + %1$s has not accessed your %2$s. + View detailed permissions usage + + Most recent access %1$s ago + + + Allowed + + + Denied + 1 day diff --git a/res/xml/allowed_denied.xml b/res/xml/allowed_denied.xml new file mode 100644 index 000000000..f944f3027 --- /dev/null +++ b/res/xml/allowed_denied.xml @@ -0,0 +1,28 @@ + + + + + + + + + + diff --git a/src/com/android/packageinstaller/permission/model/PermissionApps.java b/src/com/android/packageinstaller/permission/model/PermissionApps.java index 7e477c1ad..52f51297d 100644 --- a/src/com/android/packageinstaller/permission/model/PermissionApps.java +++ b/src/com/android/packageinstaller/permission/model/PermissionApps.java @@ -155,12 +155,12 @@ public class PermissionApps { } private List loadPermissionApps() { - PackageItemInfo groupInfo = getGroupInfo(mGroupName); + PackageItemInfo groupInfo = Utils.getGroupInfo(mGroupName, mContext); if (groupInfo == null) { return Collections.emptyList(); } - List groupPermInfos = getGroupPermissionInfos(mGroupName); + List groupPermInfos = Utils.getGroupPermissionInfos(mGroupName, mContext); if (groupPermInfos == null) { return Collections.emptyList(); } @@ -244,38 +244,6 @@ public class PermissionApps { mPermApps = result; } - private PackageItemInfo getGroupInfo(String groupName) { - try { - return mContext.getPackageManager().getPermissionGroupInfo(groupName, 0); - } catch (NameNotFoundException e) { - /* ignore */ - } - try { - return mContext.getPackageManager().getPermissionInfo(groupName, 0); - } catch (NameNotFoundException e2) { - /* ignore */ - } - return null; - } - - private List getGroupPermissionInfos(String groupName) { - try { - return Utils.getPermissionInfosForGroup(mContext.getPackageManager(), groupName); - } catch (NameNotFoundException e) { - /* ignore */ - } - try { - PermissionInfo permissionInfo = mContext.getPackageManager() - .getPermissionInfo(groupName, 0); - List permissions = new ArrayList<>(); - permissions.add(permissionInfo); - return permissions; - } catch (NameNotFoundException e2) { - /* ignore */ - } - return null; - } - private void loadGroupInfo() { PackageItemInfo info; try { diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java index 4b7d0dca9..d29359837 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java @@ -27,8 +27,10 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; +import android.content.pm.PackageItemInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; +import android.content.pm.PermissionInfo; import android.content.pm.UsesPermissionInfo; import android.graphics.drawable.Drawable; import android.os.Bundle; @@ -51,11 +53,11 @@ import androidx.fragment.app.DialogFragment; import androidx.fragment.app.Fragment; import com.android.packageinstaller.permission.model.AppPermissionGroup; -import com.android.packageinstaller.permission.model.AppPermissionUsage; import com.android.packageinstaller.permission.model.Permission; import com.android.packageinstaller.permission.utils.IconDrawableFactory; import com.android.packageinstaller.permission.utils.LocationUtils; import com.android.packageinstaller.permission.utils.PackageRemovalMonitor; +import com.android.packageinstaller.permission.utils.SafetyNetLogger; import com.android.packageinstaller.permission.utils.Utils; import com.android.permissioncontroller.R; import com.android.settingslib.RestrictedLockUtils; @@ -131,19 +133,31 @@ public class AppPermissionFragment extends PermissionsFrameFragment { createAppPermissionGroup(); - getActivity().setTitle( - getPreferenceManager().getContext().getString(R.string.app_permission_title, - mGroup.getLabel())); + if (mGroup != null) { + getActivity().setTitle( + getPreferenceManager().getContext().getString(R.string.app_permission_title, + mGroup.getLabel())); + } } private void createAppPermissionGroup() { - String packageName = getArguments().getString(Intent.EXTRA_PACKAGE_NAME); - UserHandle userHandle = getArguments().getParcelable(Intent.EXTRA_USER); Activity activity = getActivity(); Context context = getPreferenceManager().getContext(); + + String packageName = getArguments().getString(Intent.EXTRA_PACKAGE_NAME); + String groupName = getArguments().getString(Intent.EXTRA_PERMISSION_NAME); + PackageItemInfo groupInfo = Utils.getGroupInfo(groupName, context); + List groupPermInfos = Utils.getGroupPermissionInfos(groupName, context); + if (groupInfo == null || groupPermInfos == null) { + Log.i(LOG_TAG, "Illegal group: " + groupName); + activity.setResult(Activity.RESULT_CANCELED); + activity.finish(); + return; + } + UserHandle userHandle = getArguments().getParcelable(Intent.EXTRA_USER); mGroup = AppPermissionGroup.create(context, getPackageInfo(activity, packageName, userHandle), - getArguments().getString(Intent.EXTRA_PERMISSION_NAME), userHandle, false); + groupInfo, groupPermInfos, userHandle, false); if (mGroup == null || !Utils.shouldShowPermission(context, mGroup)) { Log.i(LOG_TAG, "Illegal group: " + (mGroup == null ? "null" : mGroup.getName())); @@ -172,11 +186,21 @@ public class AppPermissionFragment extends PermissionsFrameFragment { ((TextView) root.requireViewById(R.id.permission_message)).setText( context.getString(R.string.app_permission_header, mGroup.getLabel(), appLabel)); - ((TextView) root.requireViewById(R.id.usage_summary)).setText( - context.getString( - R.string.app_permission_footer_usage_summary, - appLabel, - mGroup.getLabel().toString().toLowerCase(), getUsageTimeDiffString())); + String timeDiffStr = Utils.getUsageTimeDiffString(context, mGroup); + if (timeDiffStr == null) { + ((TextView) root.requireViewById(R.id.usage_summary)).setText( + context.getString( + R.string.app_permission_footer_no_usages, + appLabel, + mGroup.getLabel().toString().toLowerCase())); + } else { + ((TextView) root.requireViewById(R.id.usage_summary)).setText( + context.getString( + R.string.app_permission_footer_usage_summary, + appLabel, + mGroup.getLabel().toString().toLowerCase(), + timeDiffStr)); + } TextView usageLink = root.requireViewById(R.id.usage_link); usageLink.setText(context.getString(R.string.app_permission_footer_usage_link)); @@ -204,6 +228,10 @@ public class AppPermissionFragment extends PermissionsFrameFragment { public void onStart() { super.onStart(); + if (mGroup == null) { + return; + } + String packageName = getArguments().getString(Intent.EXTRA_PACKAGE_NAME); UserHandle userHandle = getArguments().getParcelable(Intent.EXTRA_USER); Activity activity = getActivity(); @@ -267,27 +295,6 @@ public class AppPermissionFragment extends PermissionsFrameFragment { return super.onOptionsItemSelected(item); } - /** - * Build a string representing the amount of time passed since the most recent permission usage - * by this AppPermissionGroup. - * - * @return a string representing the amount of time since this app's most recent permission - * usage. - */ - private @NonNull String getUsageTimeDiffString() { - long mostRecentTime = 0; - List groupUsages = mGroup.getAppPermissionUsage(); - int numUsages = groupUsages.size(); - for (int usageNum = 0; usageNum < numUsages; usageNum++) { - AppPermissionUsage usage = groupUsages.get(usageNum); - mostRecentTime = Math.max(mostRecentTime, usage.getTime()); - } - if (mostRecentTime == 0) { - Log.e(LOG_TAG, "Unexpected usage time of 0."); - } - return Utils.getTimeDiffStr(getContext(), System.currentTimeMillis() - mostRecentTime); - } - private void updateButtons() { // Reset everything to the "default" state: tri-state buttons are shown with exactly one // selected and no special messages. @@ -337,6 +344,8 @@ public class AppPermissionFragment extends PermissionsFrameFragment { mDivider.setVisibility(View.VISIBLE); showRightIcon(R.drawable.ic_settings); mWidgetFrame.setOnClickListener(v -> showAllPermissions(mGroup.getName())); + + updateDetailForIndividuallyControlledPermissionGroup(); } else { if (mGroup.hasPermissionWithBackgroundMode()) { if (mGroup.getBackgroundPermissions() == null) { @@ -629,6 +638,34 @@ public class AppPermissionFragment extends PermissionsFrameFragment { return RestrictedLockUtils.getProfileOrDeviceOwner(getContext(), mGroup.getUser()); } + /** + * Update the detail in the case the permission group has individually controlled permissions. + */ + private void updateDetailForIndividuallyControlledPermissionGroup() { + int revokedCount = 0; + List permissions = mGroup.getPermissions(); + int permissionCount = permissions.size(); + for (int i = 0; i < permissionCount; i++) { + Permission permission = permissions.get(i); + if (mGroup.doesSupportRuntimePermissions() + ? !permission.isGranted() : !permission.isAppOpAllowed()) { + revokedCount++; + } + } + + int resId; + if (revokedCount == 0) { + resId = R.string.permission_revoked_none; + } else if (revokedCount == permissionCount) { + resId = R.string.permission_revoked_all; + } else { + resId = R.string.permission_revoked_count; + } + + mPermissionDetails.setText(getContext().getString(resId, revokedCount)); + mPermissionDetails.setVisibility(View.VISIBLE); + } + /** * Update the detail of a permission group that is at least partially fixed by policy. */ @@ -771,10 +808,18 @@ public class AppPermissionFragment extends PermissionsFrameFragment { if (requestGrant) { if ((changeTarget & CHANGE_FOREGROUND) != 0) { + if (!mGroup.areRuntimePermissionsGranted()) { + SafetyNetLogger.logPermissionToggled(mGroup); + } + mGroup.grantRuntimePermissions(false); } if ((changeTarget & CHANGE_BACKGROUND) != 0) { if (mGroup.getBackgroundPermissions() != null) { + if (!mGroup.getBackgroundPermissions().areRuntimePermissionsGranted()) { + SafetyNetLogger.logPermissionToggled(mGroup.getBackgroundPermissions()); + } + mGroup.getBackgroundPermissions().grantRuntimePermissions(false); } } @@ -801,11 +846,19 @@ public class AppPermissionFragment extends PermissionsFrameFragment { } else { if ((changeTarget & CHANGE_FOREGROUND) != 0 && mGroup.areRuntimePermissionsGranted()) { + if (mGroup.areRuntimePermissionsGranted()) { + SafetyNetLogger.logPermissionToggled(mGroup); + } + mGroup.revokeRuntimePermissions(false); } if ((changeTarget & CHANGE_BACKGROUND) != 0) { if (mGroup.getBackgroundPermissions() != null && mGroup.getBackgroundPermissions().areRuntimePermissionsGranted()) { + if (mGroup.getBackgroundPermissions().areRuntimePermissionsGranted()) { + SafetyNetLogger.logPermissionToggled(mGroup.getBackgroundPermissions()); + } + mGroup.getBackgroundPermissions().revokeRuntimePermissions(false); } } @@ -865,11 +918,19 @@ public class AppPermissionFragment extends PermissionsFrameFragment { void onDenyAnyWay(@ChangeTarget int changeTarget) { boolean hasDefaultPermissions = false; if ((changeTarget & CHANGE_FOREGROUND) != 0) { + if (mGroup.areRuntimePermissionsGranted()) { + SafetyNetLogger.logPermissionToggled(mGroup); + } + mGroup.revokeRuntimePermissions(false); hasDefaultPermissions = mGroup.hasGrantedByDefaultPermission(); } if ((changeTarget & CHANGE_BACKGROUND) != 0) { if (mGroup.getBackgroundPermissions() != null) { + if (mGroup.getBackgroundPermissions().areRuntimePermissionsGranted()) { + SafetyNetLogger.logPermissionToggled(mGroup.getBackgroundPermissions()); + } + mGroup.getBackgroundPermissions().revokeRuntimePermissions(false); hasDefaultPermissions |= mGroup.getBackgroundPermissions().hasGrantedByDefaultPermission(); diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java index 44c796e9c..6783c610c 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java @@ -193,13 +193,14 @@ public class AppPermissionUsageFragment extends SettingsWithHeader { continue; } + Preference pref = new PermissionUsagePreference(context, group); + pref.setTitle(usage.getPermissionGroupLabel()); long timeDiff = System.currentTimeMillis() - usage.getTime(); String timeDiffStr = Utils.getTimeDiffStr(context, timeDiff); - String summary = context.getString(R.string.app_permission_usage_summary, timeDiffStr); - Preference pref = new PermissionUsagePreference(context, usage, - usage.getPermissionGroupLabel(), summary, - Utils.applyTint(context, group.getIconResId(), - android.R.attr.colorControlNormal)); + pref.setSummary(context.getString(R.string.app_permission_usage_summary, timeDiffStr)); + pref.setIcon(Utils.applyTint(context, group.getIconResId(), + android.R.attr.colorControlNormal)); + pref.setKey(usage.getPackageName() + "," + usage.getPermissionGroupName()); screen.addPreference(pref); } diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java index 7735981ec..a4b8c631a 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java @@ -28,7 +28,6 @@ import android.net.Uri; import android.os.Bundle; import android.os.UserHandle; import android.provider.Settings; -import android.util.ArraySet; import android.util.Log; import android.view.Menu; import android.view.MenuInflater; @@ -38,12 +37,12 @@ import android.widget.Toast; import androidx.fragment.app.Fragment; import androidx.preference.Preference; +import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceScreen; import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.model.AppPermissions; import com.android.packageinstaller.permission.utils.IconDrawableFactory; -import com.android.packageinstaller.permission.utils.SafetyNetLogger; import com.android.packageinstaller.permission.utils.Utils; import com.android.permissioncontroller.R; import com.android.settingslib.HelpUtils; @@ -53,15 +52,12 @@ import com.android.settingslib.HelpUtils; * *

Shows the list of permission groups the app has requested at one permission for. */ -public final class AppPermissionsFragment extends SettingsWithHeader - implements PermissionPreference.PermissionPreferenceChangeListener, - PermissionPreference.PermissionPreferenceOwnerFragment { +public final class AppPermissionsFragment extends SettingsWithHeader { private static final String LOG_TAG = "ManagePermsFragment"; static final String EXTRA_HIDE_INFO_BUTTON = "hideInfoButton"; - private ArraySet mToggledGroups; private AppPermissions mAppPermissions; private PreferenceScreen mExtraScreen; @@ -97,6 +93,8 @@ public final class AppPermissionsFragment extends SettingsWithHeader return; } + addPreferencesFromResource(R.xml.allowed_denied); + mAppPermissions = new AppPermissions(activity, packageInfo, true, new Runnable() { @Override public void run() { @@ -182,13 +180,11 @@ public final class AppPermissionsFragment extends SettingsWithHeader return; } - PreferenceScreen screen = getPreferenceScreen(); - if (screen == null) { - screen = getPreferenceManager().createPreferenceScreen(context); - setPreferenceScreen(screen); - } + PreferenceCategory allowed = (PreferenceCategory) findPreference("allowed"); + PreferenceCategory denied = (PreferenceCategory) findPreference("denied"); - screen.removeAll(); + allowed.removeAll(); + denied.removeAll(); if (mExtraScreen != null) { mExtraScreen.removeAll(); @@ -197,6 +193,7 @@ public final class AppPermissionsFragment extends SettingsWithHeader final Preference extraPerms = new Preference(context); extraPerms.setIcon(R.drawable.ic_toc); extraPerms.setTitle(R.string.additional_permissions); + boolean extraPermsAreAllowed = false; for (AppPermissionGroup group : mAppPermissions.getPermissionGroups()) { if (!Utils.shouldShowPermission(getContext(), group)) { @@ -205,21 +202,33 @@ public final class AppPermissionsFragment extends SettingsWithHeader boolean isPlatform = group.getDeclaringPackage().equals(Utils.OS_PKG); - PermissionPreference preference = new PermissionPreference(this, group, this, 0); + Preference preference = new PermissionUsagePreference(context, group); preference.setKey(group.getName()); Drawable icon = Utils.loadDrawable(context.getPackageManager(), group.getIconPkg(), group.getIconResId()); preference.setIcon(Utils.applyTint(context, icon, android.R.attr.colorControlNormal)); preference.setTitle(group.getLabel()); + String timeDiffStr = Utils.getUsageTimeDiffString(context, group); + // Ignore {READ,WRITE}_EXTERNAL_STORAGE since they're going away. + if (timeDiffStr != null && !group.getLabel().equals("Storage")) { + preference.setSummary( + context.getString(R.string.app_permission_most_recent_summary, + timeDiffStr)); + } if (isPlatform) { - screen.addPreference(preference); + PreferenceCategory category = + group.areRuntimePermissionsGranted() ? allowed : denied; + category.addPreference(preference); } else { if (mExtraScreen == null) { mExtraScreen = getPreferenceManager().createPreferenceScreen(context); } mExtraScreen.addPreference(preference); + if (group.areRuntimePermissionsGranted()) { + extraPermsAreAllowed = true; + } } } @@ -237,33 +246,13 @@ public final class AppPermissionsFragment extends SettingsWithHeader int count = mExtraScreen.getPreferenceCount(); extraPerms.setSummary(getResources().getQuantityString( R.plurals.additional_permissions_more, count, count)); - screen.addPreference(extraPerms); + PreferenceCategory category = extraPermsAreAllowed ? allowed : denied; + category.addPreference(extraPerms); } setLoading(false /* loading */, true /* animate */); } - @Override - public void onPreferenceChanged(String key) { - if (mToggledGroups == null) { - mToggledGroups = new ArraySet<>(); - } - mToggledGroups.add(mAppPermissions.getPermissionGroup(key)); - } - - @Override - public void onPause() { - super.onPause(); - logToggledGroups(); - } - - private void logToggledGroups() { - if (mToggledGroups != null) { - SafetyNetLogger.logPermissionsToggled(mToggledGroups); - mToggledGroups = null; - } - } - private static PackageInfo getPackageInfo(Activity activity, String packageName) { try { return activity.getPackageManager().getPackageInfo( @@ -274,28 +263,6 @@ public final class AppPermissionsFragment extends SettingsWithHeader } } - @Override - public boolean shouldConfirmDefaultPermissionRevoke() { - return !mHasConfirmedRevoke; - } - - @Override - public void hasConfirmDefaultPermissionRevoke() { - mHasConfirmedRevoke = true; - } - - @Override - public void onBackgroundAccessChosen(String key, int chosenItem) { - ((PermissionPreference) getPreferenceScreen().findPreference(key)) - .onBackgroundAccessChosen(chosenItem); - } - - @Override - public void onDenyAnyWay(String key, @PermissionPreference.ChangeTarget int changeTarget) { - ((PermissionPreference) getPreferenceScreen().findPreference(key)).onDenyAnyWay( - changeTarget); - } - public static class AdditionalPermissionsFragment extends SettingsWithHeader { AppPermissionsFragment mOuterFragment; diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java index 9d03f0130..421653ec0 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java @@ -28,15 +28,14 @@ import android.view.View; import androidx.fragment.app.Fragment; import androidx.preference.Preference; +import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceScreen; import androidx.preference.SwitchPreferenceCompat; import com.android.packageinstaller.DeviceUtils; -import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.model.PermissionApps; import com.android.packageinstaller.permission.model.PermissionApps.Callback; import com.android.packageinstaller.permission.model.PermissionApps.PermissionApp; -import com.android.packageinstaller.permission.utils.SafetyNetLogger; import com.android.packageinstaller.permission.utils.Utils; import com.android.permissioncontroller.R; import com.android.settingslib.HelpUtils; @@ -46,9 +45,7 @@ import com.android.settingslib.HelpUtils; * *

Shows a list of apps which request at least on permission of this group. */ -public final class PermissionAppsFragment extends PermissionsFrameFragment implements Callback, - PermissionPreference.PermissionPreferenceOwnerFragment, - PermissionPreference.PermissionPreferenceChangeListener { +public final class PermissionAppsFragment extends PermissionsFrameFragment implements Callback { private static final String KEY_SHOW_SYSTEM_PREFS = "_showSystem"; @@ -70,7 +67,6 @@ public final class PermissionAppsFragment extends PermissionsFrameFragment imple private PreferenceScreen mExtraScreen; - private ArraySet mToggledGroups; private ArraySet mLauncherPkgs; private boolean mShowSystem; @@ -99,6 +95,8 @@ public final class PermissionAppsFragment extends PermissionsFrameFragment imple String groupName = getArguments().getString(Intent.EXTRA_PERMISSION_NAME); mPermissionApps = new PermissionApps(getActivity(), groupName, this); mPermissionApps.refresh(true); + + addPreferencesFromResource(R.xml.allowed_denied); } @Override @@ -181,17 +179,18 @@ public final class PermissionAppsFragment extends PermissionsFrameFragment imple } boolean isTelevision = DeviceUtils.isTelevision(context); - PreferenceScreen screen = getPreferenceScreen(); - if (screen == null) { - screen = getPreferenceManager().createPreferenceScreen(context); - setPreferenceScreen(screen); - } - screen.setOrderingAsAdded(false); + PreferenceCategory allowed = (PreferenceCategory) findPreference("allowed"); + PreferenceCategory denied = (PreferenceCategory) findPreference("denied"); ArraySet preferencesToRemove = new ArraySet<>(); - for (int i = 0, n = screen.getPreferenceCount(); i < n; i++) { - preferencesToRemove.add(screen.getPreference(i).getKey()); + int numPreferences = allowed.getPreferenceCount(); + for (int i = 0; i < numPreferences; i++) { + preferencesToRemove.add(allowed.getPreference(i).getKey()); + } + numPreferences = denied.getPreferenceCount(); + for (int i = 0; i < numPreferences; i++) { + preferencesToRemove.add(denied.getPreference(i).getKey()); } if (mExtraScreen != null) { for (int i = 0, n = mExtraScreen.getPreferenceCount(); i < n; i++) { @@ -213,10 +212,7 @@ public final class PermissionAppsFragment extends PermissionsFrameFragment imple String key = app.getKey(); preferencesToRemove.remove(key); - Preference existingPref = screen.findPreference(key); - if (existingPref == null && mExtraScreen != null) { - existingPref = mExtraScreen.findPreference(key); - } + Preference existingPref = findExistingPreference(key, allowed, denied); boolean isSystemApp = Utils.isSystem(app, mLauncherPkgs); @@ -228,18 +224,23 @@ public final class PermissionAppsFragment extends PermissionsFrameFragment imple if (isSystemApp && !isTelevision && !mShowSystem) { if (existingPref != null) { - screen.removePreference(existingPref); + existingPref.getParent().removePreference(existingPref); } continue; } + PreferenceCategory category = app.areRuntimePermissionsGranted() ? allowed : denied; + if (existingPref != null) { - ((PermissionPreference) existingPref).updateUi(); + // If the granted status has changed, move the permission to the new category. + if (category != existingPref.getParent()) { + existingPref.getParent().removePreference(existingPref); + category.addPreference(existingPref); + } continue; } - PermissionPreference pref = new PermissionPreference(this, app.getPermissionGroup(), - this, getResources().getDimensionPixelSize(R.dimen.secondary_app_icon_size)); + Preference pref = new PermissionUsagePreference(context, app.getPermissionGroup()); pref.setKey(app.getKey()); pref.setIcon(app.getIcon()); pref.setTitle(app.getLabel()); @@ -250,13 +251,20 @@ public final class PermissionAppsFragment extends PermissionsFrameFragment imple } mExtraScreen.addPreference(pref); } else { - screen.addPreference(pref); + category.addPreference(pref); } } if (mExtraScreen != null) { preferencesToRemove.remove(KEY_SHOW_SYSTEM_PREFS); - Preference pref = screen.findPreference(KEY_SHOW_SYSTEM_PREFS); + Preference pref = allowed.findPreference(KEY_SHOW_SYSTEM_PREFS); + + int grantedCount = 0; + for (int i = 0, n = mExtraScreen.getPreferenceCount(); i < n; i++) { + if (((SwitchPreferenceCompat) mExtraScreen.getPreference(i)).isChecked()) { + grantedCount++; + } + } if (pref == null) { pref = new Preference(context); @@ -274,28 +282,18 @@ public final class PermissionAppsFragment extends PermissionsFrameFragment imple .commit(); return true; }); - screen.addPreference(pref); + PreferenceCategory category = grantedCount > 0 ? allowed : denied; + category.addPreference(pref); } - int grantedCount = 0; - for (int i = 0, n = mExtraScreen.getPreferenceCount(); i < n; i++) { - if (((SwitchPreferenceCompat) mExtraScreen.getPreference(i)).isChecked()) { - grantedCount++; - } - } pref.setSummary(getString(R.string.app_permissions_group_summary, grantedCount, mExtraScreen.getPreferenceCount())); } for (String key : preferencesToRemove) { - Preference pref = screen.findPreference(key); + Preference pref = findExistingPreference(key, allowed, denied); if (pref != null) { - screen.removePreference(pref); - } else if (mExtraScreen != null) { - pref = mExtraScreen.findPreference(key); - if (pref != null) { - mExtraScreen.removePreference(pref); - } + pref.getParent().removePreference(pref); } } @@ -306,47 +304,23 @@ public final class PermissionAppsFragment extends PermissionsFrameFragment imple } } - @Override - public void onPreferenceChanged(String key) { - if (mToggledGroups == null) { - mToggledGroups = new ArraySet<>(); + private Preference findExistingPreference(String key, PreferenceCategory allowed, + PreferenceCategory denied) { + Preference preference = allowed.findPreference(key); + if (preference != null) { + return preference; } - mToggledGroups.add(mPermissionApps.getApp(key).getPermissionGroup()); - } - - @Override - public void onPause() { - super.onPause(); - logToggledGroups(); - } - - private void logToggledGroups() { - if (mToggledGroups != null) { - SafetyNetLogger.logPermissionsToggled(mToggledGroups); - mToggledGroups = null; + preference = denied.findPreference(key); + if (preference != null) { + return preference; } - } - - @Override - public void onBackgroundAccessChosen(String key, int chosenItem) { - ((PermissionPreference) getPreferenceScreen().findPreference(key)) - .onBackgroundAccessChosen(chosenItem); - } - - @Override - public void onDenyAnyWay(String key, @PermissionPreference.ChangeTarget int changeTarget) { - ((PermissionPreference) getPreferenceScreen().findPreference(key)).onDenyAnyWay( - changeTarget); - } - - @Override - public boolean shouldConfirmDefaultPermissionRevoke() { - return true; - } - - @Override - public void hasConfirmDefaultPermissionRevoke() { - // do nothing + if (mExtraScreen != null) { + preference = mExtraScreen.findPreference(key); + if (preference != null) { + return preference; + } + } + return null; } public static class SystemAppsFragment extends PermissionsFrameFragment implements Callback { diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java index 1edc2192c..f9a1353c0 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java @@ -270,6 +270,7 @@ public class PermissionUsageFragment extends PermissionsFrameFragment implements Context context = getPreferenceManager().getContext(); List appPermissionUsages = new ArrayList<>(); List groups = mPermissionGroups.getGroups(); + Map usageToGroup = new ArrayMap<>(); Map usageToApp = new ArrayMap<>(); int numGroups = groups.size(); for (int groupNum = 0; groupNum < numGroups; groupNum++) { @@ -317,6 +318,7 @@ public class PermissionUsageFragment extends PermissionsFrameFragment implements if (!isSystemApp || mShowSystem) { appPermissionUsages.add(usage); + usageToGroup.put(usage, group); usageToApp.put(usage, permApp); } } @@ -333,13 +335,16 @@ public class PermissionUsageFragment extends PermissionsFrameFragment implements + usage.getPermissionGroupName())) { continue; } + AppPermissionGroup group = usageToGroup.get(usage); PermissionApp permApp = usageToApp.get(usage); + Preference pref = new PermissionUsagePreference(context, group); + pref.setTitle(permApp.getLabel()); long timeDiff = System.currentTimeMillis() - usage.getTime(); String timeDiffStr = Utils.getTimeDiffStr(context, timeDiff); - String summary = context.getString(R.string.permission_usage_summary, - usage.getPermissionGroupLabel(), timeDiffStr); - Preference pref = new PermissionUsagePreference(context, usage, permApp.getLabel(), - summary, permApp.getIcon()); + pref.setSummary(context.getString(R.string.permission_usage_summary, + usage.getPermissionGroupLabel(), timeDiffStr)); + pref.setIcon(permApp.getIcon()); + pref.setKey(usage.getPackageName() + "," + usage.getPermissionGroupName()); screen.addPreference(pref); } } diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsagePreference.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsagePreference.java index a99f5759d..ba1859b97 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsagePreference.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsagePreference.java @@ -18,36 +18,24 @@ package com.android.packageinstaller.permission.ui.handheld; import android.content.Context; import android.content.Intent; -import android.graphics.drawable.Drawable; -import android.os.UserHandle; import androidx.annotation.NonNull; import androidx.preference.Preference; -import com.android.packageinstaller.permission.model.AppPermissionUsage; +import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.ui.AppPermissionActivity; /** * A preference for representing a permission usage by an app. */ public class PermissionUsagePreference extends Preference { - public PermissionUsagePreference(@NonNull Context context, @NonNull AppPermissionUsage usage, - @NonNull CharSequence title, @NonNull String summary, @NonNull Drawable icon) { + public PermissionUsagePreference(@NonNull Context context, @NonNull AppPermissionGroup group) { super(context); - updateUi(context, usage, title, summary, icon); - } - - private void updateUi(@NonNull Context context, @NonNull AppPermissionUsage usage, - @NonNull CharSequence title, @NonNull String summary, @NonNull Drawable icon) { - setKey(usage.getPackageName() + "," + usage.getPermissionGroupName()); - setTitle(title); - setSummary(summary); - setIcon(icon); setOnPreferenceClickListener(preference -> { Intent intent = new Intent(context, AppPermissionActivity.class); - intent.putExtra(Intent.EXTRA_PACKAGE_NAME, usage.getPackageName()); - intent.putExtra(Intent.EXTRA_PERMISSION_NAME, usage.getPermissionName()); - intent.putExtra(Intent.EXTRA_USER, UserHandle.getUserHandleForUid(usage.getUid())); + intent.putExtra(Intent.EXTRA_PACKAGE_NAME, group.getApp().packageName); + intent.putExtra(Intent.EXTRA_PERMISSION_NAME, group.getName()); + intent.putExtra(Intent.EXTRA_USER, group.getUser()); context.startActivity(intent); return true; }); diff --git a/src/com/android/packageinstaller/permission/utils/SafetyNetLogger.java b/src/com/android/packageinstaller/permission/utils/SafetyNetLogger.java index 7773294b0..a0b59213f 100644 --- a/src/com/android/packageinstaller/permission/utils/SafetyNetLogger.java +++ b/src/com/android/packageinstaller/permission/utils/SafetyNetLogger.java @@ -84,6 +84,17 @@ public final class SafetyNetLogger { } } + /** + * Log that a permission group has been toggled for the purpose of safety net. + * + * @param group The group toggled. + */ + public static void logPermissionToggled(AppPermissionGroup group) { + ArraySet groups = new ArraySet(1); + groups.add(group); + logPermissionsToggled(groups); + } + private static void buildChangedPermissionForGroup(AppPermissionGroup group, StringBuilder builder) { int permissionCount = group.getPermissions().size(); diff --git a/src/com/android/packageinstaller/permission/utils/Utils.java b/src/com/android/packageinstaller/permission/utils/Utils.java index 85be02fd3..9d5e1c908 100644 --- a/src/com/android/packageinstaller/permission/utils/Utils.java +++ b/src/com/android/packageinstaller/permission/utils/Utils.java @@ -34,7 +34,9 @@ import android.Manifest; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; +import android.content.pm.PackageItemInfo; import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.PermissionInfo; import android.content.pm.ResolveInfo; import android.content.res.Resources; @@ -56,6 +58,7 @@ import androidx.core.text.BidiFormatter; import androidx.core.util.Preconditions; import com.android.packageinstaller.permission.model.AppPermissionGroup; +import com.android.packageinstaller.permission.model.AppPermissionUsage; import com.android.packageinstaller.permission.model.AppPermissions; import com.android.packageinstaller.permission.model.PermissionApps.PermissionApp; import com.android.permissioncontroller.R; @@ -259,7 +262,7 @@ public final class Utils { * @param pm Package manager to use to resolve permission infos * @param group the group * - * @return The infos of permissions belonging to the group or an empty list if the group is not + * @return The infos of permissions belonging to the group or an empty list if the group * does not have runtime permissions */ public static @NonNull List getPermissionInfosForGroup( @@ -271,6 +274,57 @@ public final class Utils { return permissions; } + /** + * Get the {@link PackageItemInfo infos} for the given permission group. + * + * @param groupName the group + * @param context the {@code Context} to retrieve {@code PackageManager} + * + * @return The info of permission group or null if the group does not have runtime permissions. + */ + public static @Nullable PackageItemInfo getGroupInfo(@NonNull String groupName, + @NonNull Context context) { + try { + return context.getPackageManager().getPermissionGroupInfo(groupName, 0); + } catch (NameNotFoundException e) { + /* ignore */ + } + try { + return context.getPackageManager().getPermissionInfo(groupName, 0); + } catch (NameNotFoundException e) { + /* ignore */ + } + return null; + } + + /** + * Get the {@link PermissionInfo infos} for all permission infos belonging to a group. + * + * @param groupName the group + * @param context the {@code Context} to retrieve {@code PackageManager} + * + * @return The infos of permissions belonging to the group or null if the group does not have + * runtime permissions. + */ + public static @Nullable List getGroupPermissionInfos(@NonNull String groupName, + @NonNull Context context) { + try { + return Utils.getPermissionInfosForGroup(context.getPackageManager(), groupName); + } catch (NameNotFoundException e) { + /* ignore */ + } + try { + PermissionInfo permissionInfo = context.getPackageManager() + .getPermissionInfo(groupName, 0); + List permissions = new ArrayList<>(); + permissions.add(permissionInfo); + return permissions; + } catch (NameNotFoundException e) { + /* ignore */ + } + return null; + } + /** * Get the label for an application. * @@ -413,6 +467,28 @@ public final class Utils { group.getDescription()), 0); } + /** + * Build a string representing the amount of time passed since the most recent permission usage + * by this AppPermissionGroup. + * + * @return a string representing the amount of time since this app's most recent permission + * usage or null if there are no usages. + */ + public static @Nullable String getUsageTimeDiffString(@NonNull Context context, + @NonNull AppPermissionGroup group) { + long mostRecentTime = 0; + List groupUsages = group.getAppPermissionUsage(); + int numUsages = groupUsages.size(); + for (int usageNum = 0; usageNum < numUsages; usageNum++) { + AppPermissionUsage usage = groupUsages.get(usageNum); + mostRecentTime = Math.max(mostRecentTime, usage.getTime()); + } + if (mostRecentTime <= 0) { + return null; + } + return getTimeDiffStr(context, System.currentTimeMillis() - mostRecentTime); + } + /** * Build a string representing the number of milliseconds passed in. It rounds to the nearest * unit. For example, given a duration of 3500 and an English locale, this can return -- GitLab From 3d41ff8425499467677b881c776ce6d796025368 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Mon, 3 Dec 2018 13:55:37 -0800 Subject: [PATCH 166/701] Show permission group icon on the right of PermissionUsageFragment. This modifies PermissionUsageFragment so that each entry contains the icon for the permission group on the right. Bug: 63532550 Test: Open all users of PermissionUsagePreference and see permission group icons only on PermissionUsageFragment. Change-Id: Id08609c0165a63cf46fabe43654d0da47518a349 --- res/layout/image_view.xml | 30 ++++++++++++++++ .../ui/handheld/PermissionUsageFragment.java | 4 ++- .../handheld/PermissionUsagePreference.java | 36 ++++++++++++++++--- 3 files changed, 65 insertions(+), 5 deletions(-) create mode 100644 res/layout/image_view.xml diff --git a/res/layout/image_view.xml b/res/layout/image_view.xml new file mode 100644 index 000000000..3cd19e67e --- /dev/null +++ b/res/layout/image_view.xml @@ -0,0 +1,30 @@ + + + + + + + + + diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java index f9a1353c0..a33b9e7db 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java @@ -337,7 +337,9 @@ public class PermissionUsageFragment extends PermissionsFrameFragment implements } AppPermissionGroup group = usageToGroup.get(usage); PermissionApp permApp = usageToApp.get(usage); - Preference pref = new PermissionUsagePreference(context, group); + Preference pref = new PermissionUsagePreference(context, group, + Utils.applyTint(context, group.getIconResId(), + android.R.attr.colorControlNormal)); pref.setTitle(permApp.getLabel()); long timeDiff = System.currentTimeMillis() - usage.getTime(); String timeDiffStr = Utils.getTimeDiffStr(context, timeDiff); diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsagePreference.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsagePreference.java index ba1859b97..c2701f916 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsagePreference.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsagePreference.java @@ -18,26 +18,54 @@ package com.android.packageinstaller.permission.ui.handheld; import android.content.Context; import android.content.Intent; +import android.graphics.drawable.Drawable; +import android.view.View; +import android.widget.ImageView; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.preference.Preference; +import androidx.preference.PreferenceViewHolder; import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.ui.AppPermissionActivity; +import com.android.permissioncontroller.R; /** * A preference for representing a permission usage by an app. */ public class PermissionUsagePreference extends Preference { - public PermissionUsagePreference(@NonNull Context context, @NonNull AppPermissionGroup group) { + private final @NonNull AppPermissionGroup mGroup; + private final @Nullable Drawable mWidgetIcon; + + public PermissionUsagePreference(@NonNull Context context, @NonNull AppPermissionGroup group, + @Nullable Drawable widgetIcon) { super(context); + mGroup = group; + mWidgetIcon = widgetIcon; + if (mWidgetIcon != null) { + setWidgetLayoutResource(R.layout.image_view); + } setOnPreferenceClickListener(preference -> { Intent intent = new Intent(context, AppPermissionActivity.class); - intent.putExtra(Intent.EXTRA_PACKAGE_NAME, group.getApp().packageName); - intent.putExtra(Intent.EXTRA_PERMISSION_NAME, group.getName()); - intent.putExtra(Intent.EXTRA_USER, group.getUser()); + intent.putExtra(Intent.EXTRA_PACKAGE_NAME, mGroup.getApp().packageName); + intent.putExtra(Intent.EXTRA_PERMISSION_NAME, mGroup.getName()); + intent.putExtra(Intent.EXTRA_USER, mGroup.getUser()); context.startActivity(intent); return true; }); } + + public PermissionUsagePreference(@NonNull Context context, @NonNull AppPermissionGroup group) { + this(context, group, null); + } + + @Override + public void onBindViewHolder(PreferenceViewHolder holder) { + super.onBindViewHolder(holder); + if (mWidgetIcon != null) { + View widgetFrame = holder.findViewById(android.R.id.widget_frame); + ((ImageView) widgetFrame.findViewById(R.id.icon)).setImageDrawable(mWidgetIcon); + } + } } -- GitLab From 75931d332672d3c8e49be88ca0be6f59c1f2b4e5 Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Thu, 29 Nov 2018 18:22:39 -0800 Subject: [PATCH 167/701] Add activity to manage a single default app. This change adds the activity to manage a single default app and its qualifying apps. Bug: 110557011 Test: manual Change-Id: I5fea8dd4e133459b7c19d6632804d722383935b6 --- AndroidManifest.xml | 3 + res/layout/preference_widget_radio_button.xml | 33 ++++ res/values/strings.xml | 48 ++--- .../role/ui/AppIconRadioButtonPreference.java | 71 +++++++ .../role/ui/DefaultAppActivity.java | 71 +++++++ .../role/ui/DefaultAppFragment.java | 181 ++++++++++++++++++ .../role/ui/DefaultAppListFragment.java | 5 +- .../role/ui/RadioButtonPreference.java | 85 ++++++++ .../packageinstaller/role/ui/RoleInfo.java | 57 ++++++ .../role/ui/RoleLiveData.java | 75 ++++++++ .../role/ui/RoleViewModel.java | 70 +++++++ 11 files changed, 675 insertions(+), 24 deletions(-) create mode 100644 res/layout/preference_widget_radio_button.xml create mode 100644 src/com/android/packageinstaller/role/ui/AppIconRadioButtonPreference.java create mode 100644 src/com/android/packageinstaller/role/ui/DefaultAppActivity.java create mode 100644 src/com/android/packageinstaller/role/ui/DefaultAppFragment.java create mode 100644 src/com/android/packageinstaller/role/ui/RadioButtonPreference.java create mode 100644 src/com/android/packageinstaller/role/ui/RoleInfo.java create mode 100644 src/com/android/packageinstaller/role/ui/RoleLiveData.java create mode 100644 src/com/android/packageinstaller/role/ui/RoleViewModel.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index a3bcda693..45e32f961 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -137,6 +137,9 @@ + + + + + + + + + diff --git a/res/values/strings.xml b/res/values/strings.xml index 8953fb5f9..0c3967a43 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -341,29 +341,6 @@ This app can always access your location. Tap to change. - - Default apps - - - - - - - No default apps - - - - - Phone app - - SMS app - - Browser app - - Gallery app - - Music app - The app developer says your data may be: @@ -403,4 +380,29 @@ The app developer did not specify how the app uses your data. + + Default apps + + + + + + + No default apps + + + No apps + + + + + Phone app + + SMS app + + Browser app + + Gallery app + + Music app diff --git a/src/com/android/packageinstaller/role/ui/AppIconRadioButtonPreference.java b/src/com/android/packageinstaller/role/ui/AppIconRadioButtonPreference.java new file mode 100644 index 000000000..5e982d84f --- /dev/null +++ b/src/com/android/packageinstaller/role/ui/AppIconRadioButtonPreference.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.packageinstaller.role.ui; + +import android.content.Context; +import android.util.AttributeSet; + +import androidx.annotation.AttrRes; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.StyleRes; +import androidx.preference.PreferenceViewHolder; + +/** + * {@link RadioButtonPreference} with {@link AppIconPreference.Mixin}. + */ +public class AppIconRadioButtonPreference extends RadioButtonPreference { + + private AppIconPreference.Mixin mMixin; + + public AppIconRadioButtonPreference(@NonNull Context context) { + super(context); + + init(); + } + + public AppIconRadioButtonPreference(@NonNull Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + + init(); + } + + public AppIconRadioButtonPreference(@NonNull Context context, @Nullable AttributeSet attrs, + @AttrRes int defStyleAttr) { + super(context, attrs, defStyleAttr); + + init(); + } + + public AppIconRadioButtonPreference(@NonNull Context context, @Nullable AttributeSet attrs, + @AttrRes int defStyleAttr, @StyleRes int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + + init(); + } + + private void init() { + mMixin = new AppIconPreference.Mixin(getContext()); + } + + @Override + public void onBindViewHolder(@NonNull PreferenceViewHolder holder) { + super.onBindViewHolder(holder); + + mMixin.onBindViewHolder(holder); + } +} diff --git a/src/com/android/packageinstaller/role/ui/DefaultAppActivity.java b/src/com/android/packageinstaller/role/ui/DefaultAppActivity.java new file mode 100644 index 000000000..b1ae2c0a2 --- /dev/null +++ b/src/com/android/packageinstaller/role/ui/DefaultAppActivity.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.packageinstaller.role.ui; + +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentActivity; + +import com.android.packageinstaller.role.model.Role; +import com.android.packageinstaller.role.model.Roles; + +/** + * Activity for a default app. + */ +public class DefaultAppActivity extends FragmentActivity { + + private static final String LOG_TAG = DefaultAppActivity.class.getSimpleName(); + + /** + * Create an intent for starting this activity. + * + * @param roleName the name of the role for the default app + * @param context the context to create the intent + * + * @return an intent to start this activity + */ + @NonNull + public static Intent createIntent(@NonNull String roleName, @NonNull Context context) { + return new Intent(context, DefaultAppActivity.class) + .putExtra(DefaultAppFragment.EXTRA_ROLE_NAME, roleName); + } + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + String roleName = getIntent().getStringExtra(DefaultAppFragment.EXTRA_ROLE_NAME); + Role role = Roles.getRoles(this).get(roleName); + if (role == null) { + Log.e(LOG_TAG, "Unknown role: " + roleName); + finish(); + return; + } + + if (savedInstanceState == null) { + DefaultAppFragment fragment = DefaultAppFragment.newInstance(roleName); + getSupportFragmentManager().beginTransaction() + .add(android.R.id.content, fragment) + .commit(); + } + } +} diff --git a/src/com/android/packageinstaller/role/ui/DefaultAppFragment.java b/src/com/android/packageinstaller/role/ui/DefaultAppFragment.java new file mode 100644 index 000000000..a7215cbb6 --- /dev/null +++ b/src/com/android/packageinstaller/role/ui/DefaultAppFragment.java @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.packageinstaller.role.ui; + +import android.app.Activity; +import android.app.role.RoleManager; +import android.app.role.RoleManagerCallback; +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.os.Bundle; +import android.os.Process; +import android.os.UserHandle; +import android.util.ArrayMap; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.StringRes; +import androidx.lifecycle.ViewModelProviders; +import androidx.preference.Preference; +import androidx.preference.PreferenceManager; +import androidx.preference.PreferenceScreen; +import androidx.preference.TwoStatePreference; + +import com.android.packageinstaller.permission.utils.IconDrawableFactory; +import com.android.packageinstaller.permission.utils.Utils; +import com.android.packageinstaller.role.model.Role; +import com.android.packageinstaller.role.model.Roles; +import com.android.permissioncontroller.R; + +import java.util.List; + +/** + * Fragment for a default app. + */ +public class DefaultAppFragment extends SettingsFragment + implements Preference.OnPreferenceClickListener { + + private static final String LOG_TAG = DefaultAppFragment.class.getSimpleName(); + + public static final String EXTRA_ROLE_NAME = + "com.android.packageinstaller.role.ui.extra.ROLE_NAME"; + + private String mRoleName; + + private Role mRole; + + private RoleViewModel mViewModel; + + /** + * Create a new instance of this fragment. + * + * @param roleName the name of the role to be managed + * + * @return a new instance of this fragment + */ + @NonNull + public static DefaultAppFragment newInstance(@NonNull String roleName) { + DefaultAppFragment fragment = new DefaultAppFragment(); + Bundle arguments = new Bundle(); + arguments.putString(EXTRA_ROLE_NAME, roleName); + fragment.setArguments(arguments); + return fragment; + } + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + mRoleName = getArguments().getString(EXTRA_ROLE_NAME); + } + + @Override + public void onActivityCreated(@Nullable Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + Activity activity = requireActivity(); + mRole = Roles.getRoles(activity).get(mRoleName); + activity.setTitle(mRole.getLabelResource()); + + mViewModel = ViewModelProviders.of(this, new RoleViewModel.Factory(mRole, + activity.getApplication())).get(RoleViewModel.class); + mViewModel.getLiveData().observe(this, this::onRoleInfoChanged); + } + + @Override + @StringRes + protected int getEmptyTextResource() { + return R.string.no_apps_for_default_app; + } + + private void onRoleInfoChanged(@NonNull RoleInfo roleInfo) { + PreferenceManager preferenceManager = getPreferenceManager(); + Context context = preferenceManager.getContext(); + + PreferenceScreen preferenceScreen = getPreferenceScreen(); + ArrayMap oldPreferences = new ArrayMap<>(); + if (preferenceScreen == null) { + preferenceScreen = preferenceManager.createPreferenceScreen(context); + setPreferenceScreen(preferenceScreen); + } else { + for (int i = preferenceScreen.getPreferenceCount() - 1; i >= 0; --i) { + Preference preference = preferenceScreen.getPreference(i); + + preferenceScreen.removePreference(preference); + oldPreferences.put(preference.getKey(), preference); + } + } + + List qualifyingApplicationInfos = roleInfo.getQualifyingApplicationInfos(); + List holderPackageNames = roleInfo.getHolderPackageNames(); + int qualifyingApplicationInfosSize = qualifyingApplicationInfos.size(); + for (int i = 0; i < qualifyingApplicationInfosSize; i++) { + ApplicationInfo qualifyingApplicationInfo = qualifyingApplicationInfos.get(i); + + TwoStatePreference preference = (TwoStatePreference) oldPreferences.get( + qualifyingApplicationInfo.packageName); + if (preference == null) { + // TODO: STOPSHIP: Support multiple role holders. + preference = new AppIconRadioButtonPreference(context); + preference.setKey(qualifyingApplicationInfo.packageName); + preference.setIcon(IconDrawableFactory.getBadgedIcon(context, + qualifyingApplicationInfo, UserHandle.getUserHandleForUid( + qualifyingApplicationInfo.uid))); + preference.setTitle(Utils.getAppLabel(qualifyingApplicationInfo, context)); + preference.setPersistent(false); + preference.setOnPreferenceClickListener(this); + } + + preference.setChecked(holderPackageNames.contains( + qualifyingApplicationInfo.packageName)); + + // TODO: Ordering? + preferenceScreen.addPreference(preference); + } + + updateState(); + } + + @Override + public boolean onPreferenceClick(@NonNull Preference preference) { + // TODO: STOPSHIP: Support multiple role holders. + String packageName = preference.getKey(); + Log.i(LOG_TAG, "Adding application as role holder, role: " + mRoleName + ", package: " + + packageName); + Context context = requireContext(); + RoleManager roleManager = context.getSystemService(RoleManager.class); + roleManager.addRoleHolderAsUser(mRoleName, packageName, Process.myUserHandle(), + context.getMainExecutor(), new RoleManagerCallback() { + @Override + public void onSuccess() { + Log.i(LOG_TAG, "Added application as role holder, role: " + mRoleName + + ", package: " + packageName); + // TODO: STOPSHIP: Use role holder observation instead. + mViewModel.getLiveData().loadValue(); + } + @Override + public void onFailure() { + Log.i(LOG_TAG, "Failed to add application as role holder, role: " + + mRoleName + ", package: " + packageName); + // TODO: STOPSHIP: Use role holder observation instead. + mViewModel.getLiveData().loadValue(); + } + }); + return true; + } +} diff --git a/src/com/android/packageinstaller/role/ui/DefaultAppListFragment.java b/src/com/android/packageinstaller/role/ui/DefaultAppListFragment.java index 536252d6c..4728f61f5 100644 --- a/src/com/android/packageinstaller/role/ui/DefaultAppListFragment.java +++ b/src/com/android/packageinstaller/role/ui/DefaultAppListFragment.java @@ -17,6 +17,7 @@ package com.android.packageinstaller.role.ui; import android.content.Context; +import android.content.Intent; import android.content.pm.ApplicationInfo; import android.os.Bundle; import android.os.UserHandle; @@ -130,7 +131,9 @@ public class DefaultAppListFragment extends SettingsFragment @Override public boolean onPreferenceClick(@NonNull Preference preference) { - // TODO + String roleName = preference.getKey(); + Intent intent = DefaultAppActivity.createIntent(roleName, requireContext()); + startActivity(intent); return true; } } diff --git a/src/com/android/packageinstaller/role/ui/RadioButtonPreference.java b/src/com/android/packageinstaller/role/ui/RadioButtonPreference.java new file mode 100644 index 000000000..e43241967 --- /dev/null +++ b/src/com/android/packageinstaller/role/ui/RadioButtonPreference.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.packageinstaller.role.ui; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.ViewGroup; +import android.widget.RadioButton; + +import androidx.annotation.AttrRes; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.StyleRes; +import androidx.core.content.res.TypedArrayUtils; +import androidx.preference.PreferenceViewHolder; +import androidx.preference.TwoStatePreference; + +import com.android.permissioncontroller.R; + +/** + * {@link TwoStatePreference} with a radio button. + * + * @see com.android.settings.widget.RadioButtonPreference + */ +public class RadioButtonPreference extends TwoStatePreference { + + public RadioButtonPreference(@NonNull Context context) { + this(context, null); + } + + public RadioButtonPreference(@NonNull Context context, @Nullable AttributeSet attrs) { + this(context, attrs, TypedArrayUtils.getAttr(context, R.attr.preferenceStyle, + android.R.attr.preferenceStyle)); + } + + public RadioButtonPreference(@NonNull Context context, @Nullable AttributeSet attrs, + @AttrRes int defStyleAttr) { + this(context, attrs, defStyleAttr, 0); + } + + public RadioButtonPreference(@NonNull Context context, @Nullable AttributeSet attrs, + @AttrRes int defStyleAttr, @StyleRes int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + + setWidgetLayoutResource(R.layout.preference_widget_radio_button); + } + + @Override + public void onBindViewHolder(@NonNull PreferenceViewHolder holder) { + super.onBindViewHolder(holder); + + ViewGroup viewGroup = (ViewGroup) holder.itemView; + ViewGroup widgetFrame = (ViewGroup) holder.findViewById(android.R.id.widget_frame); + if (viewGroup.indexOfChild(widgetFrame) != 0) { + widgetFrame.setPaddingRelative(widgetFrame.getPaddingEnd(), widgetFrame.getPaddingTop(), + widgetFrame.getPaddingStart(), widgetFrame.getPaddingBottom()); + viewGroup.removeView(widgetFrame); + viewGroup.addView(widgetFrame, 0); + viewGroup.setPaddingRelative(0, viewGroup.getPaddingTop(), viewGroup.getPaddingEnd(), + viewGroup.getPaddingBottom()); + } + + RadioButton radioButton = (RadioButton) holder.findViewById(R.id.radio_button); + radioButton.setChecked(mChecked); + } + + @Override + protected void onClick() { + // Ignored. + } +} diff --git a/src/com/android/packageinstaller/role/ui/RoleInfo.java b/src/com/android/packageinstaller/role/ui/RoleInfo.java new file mode 100644 index 000000000..380ca4fc6 --- /dev/null +++ b/src/com/android/packageinstaller/role/ui/RoleInfo.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.packageinstaller.role.ui; + +import android.content.pm.ApplicationInfo; + +import androidx.annotation.NonNull; + +import java.util.List; + +/** + * Information about a role. + */ +public class RoleInfo { + + /** + * The list of {@link ApplicationInfo} of applications qualifying for this role. + */ + @NonNull + private final List mQualifyingApplicationInfos; + + /** + * The list of package names of applications holding this role. + */ + @NonNull + private final List mHolderPackageNames; + + public RoleInfo(@NonNull List qualifyingApplicationInfos, + @NonNull List holderPackageNames) { + mQualifyingApplicationInfos = qualifyingApplicationInfos; + mHolderPackageNames = holderPackageNames; + } + + @NonNull + public List getQualifyingApplicationInfos() { + return mQualifyingApplicationInfos; + } + + @NonNull + public List getHolderPackageNames() { + return mHolderPackageNames; + } +} diff --git a/src/com/android/packageinstaller/role/ui/RoleLiveData.java b/src/com/android/packageinstaller/role/ui/RoleLiveData.java new file mode 100644 index 000000000..02b62e288 --- /dev/null +++ b/src/com/android/packageinstaller/role/ui/RoleLiveData.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.packageinstaller.role.ui; + +import android.app.role.RoleManager; +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.WorkerThread; +import androidx.lifecycle.LiveData; + +import com.android.packageinstaller.role.model.Role; +import com.android.packageinstaller.role.utils.PackageUtils; + +import java.util.ArrayList; +import java.util.List; + +/** + * {@link LiveData} for a role. + */ +public class RoleLiveData extends AsyncTaskLiveData { + + private static final String LOG_TAG = RoleLiveData.class.getSimpleName(); + + private final Role mRole; + private final Context mContext; + + public RoleLiveData(@NonNull Role role, @NonNull Context context) { + mRole = role; + mContext = context; + + loadValue(); + } + + @Override + @WorkerThread + protected RoleInfo loadValueInBackground() { + List qualifyingPackageNames = mRole.getQualifyingPackages(mContext); + List qualifyingApplicationInfos = new ArrayList<>(); + int qualifyingPackageNamesSize = qualifyingPackageNames.size(); + for (int i = 0; i < qualifyingPackageNamesSize; i++) { + String qualifyingPackageName = qualifyingPackageNames.get(i); + + ApplicationInfo qualifyingApplicationInfo = PackageUtils.getApplicationInfo( + qualifyingPackageName, mContext); + if (qualifyingApplicationInfo == null) { + Log.w(LOG_TAG, "Cannot get ApplicationInfo for application, skipping: " + + qualifyingPackageName); + continue; + } + qualifyingApplicationInfos.add(qualifyingApplicationInfo); + } + + RoleManager roleManager = mContext.getSystemService(RoleManager.class); + List holderPackageNames = roleManager.getRoleHolders(mRole.getName()); + + return new RoleInfo(qualifyingApplicationInfos, holderPackageNames); + } +} diff --git a/src/com/android/packageinstaller/role/ui/RoleViewModel.java b/src/com/android/packageinstaller/role/ui/RoleViewModel.java new file mode 100644 index 000000000..0f25cfd08 --- /dev/null +++ b/src/com/android/packageinstaller/role/ui/RoleViewModel.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.packageinstaller.role.ui; + +import android.app.Application; + +import androidx.annotation.NonNull; +import androidx.lifecycle.AndroidViewModel; +import androidx.lifecycle.ViewModel; +import androidx.lifecycle.ViewModelProvider; + +import com.android.packageinstaller.role.model.Role; + +/** + * {@link ViewModel} for a role. + */ +public class RoleViewModel extends AndroidViewModel { + + @NonNull + private final RoleLiveData mLiveData; + + public RoleViewModel(@NonNull Role role, @NonNull Application application) { + super(application); + + mLiveData = new RoleLiveData(role, application); + } + + @NonNull + public RoleLiveData getLiveData() { + return mLiveData; + } + + /** + * {@link ViewModelProvider.Factory} for {@link RoleViewModel}. + */ + public static class Factory implements ViewModelProvider.Factory { + + @NonNull + private Role mRole; + + @NonNull + private Application mApplication; + + public Factory(@NonNull Role role, @NonNull Application application) { + mRole = role; + mApplication = application; + } + + @NonNull + @Override + public T create(@NonNull Class modelClass) { + //noinspection unchecked + return (T) new RoleViewModel(mRole, mApplication); + } + } +} -- GitLab From 88420480ada859d4ee907bd206ae4cd321829d41 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Tue, 4 Dec 2018 16:22:07 -0800 Subject: [PATCH 168/701] Allow passing a permission name to PermissionUsageFragment. You can now pass a permission name to PermissionUsageFragment via EXTRA_PERMISSION_NAME, which will pre-select the given permission's group in the permission group filter. In the process, I fixed a bug in restoring the saved filter state. Bug: 120222495 Test: Launch page with and without argument, see correct filter. Change-Id: I60ec7b574bf0917b28a387199ec8d80e152f4c08 --- .../ui/ManagePermissionsActivity.java | 3 +- .../ui/handheld/PermissionUsageFragment.java | 35 ++++++++++++++----- .../permission/utils/Utils.java | 2 +- 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/src/com/android/packageinstaller/permission/ui/ManagePermissionsActivity.java b/src/com/android/packageinstaller/permission/ui/ManagePermissionsActivity.java index 5402185d1..fa762facc 100644 --- a/src/com/android/packageinstaller/permission/ui/ManagePermissionsActivity.java +++ b/src/com/android/packageinstaller/permission/ui/ManagePermissionsActivity.java @@ -66,7 +66,8 @@ public final class ManagePermissionsActivity extends FragmentActivity { verifyIntent(this, getIntent()); // fall through case Intent.ACTION_REVIEW_PERMISSION_USAGE: - androidXFragment = PermissionUsageFragment.newInstance(); + permissionName = getIntent().getStringExtra(Intent.EXTRA_PERMISSION_NAME); + androidXFragment = PermissionUsageFragment.newInstance(permissionName); break; case Intent.ACTION_MANAGE_APP_PERMISSIONS: { diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java index 1edc2192c..f3bae7560 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java @@ -18,9 +18,11 @@ package com.android.packageinstaller.permission.ui.handheld; import android.app.ActionBar; import android.content.Context; +import android.content.Intent; import android.os.Bundle; import android.util.ArrayMap; import android.util.ArraySet; +import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -32,6 +34,7 @@ import android.widget.AdapterView.OnItemSelectedListener; import android.widget.Spinner; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.preference.Preference; import androidx.preference.PreferenceScreen; @@ -61,6 +64,7 @@ import java.util.Set; */ public class PermissionUsageFragment extends PermissionsFrameFragment implements PermissionGroups.PermissionsGroupsChangeCallback, OnItemSelectedListener { + private static final String LOG_TAG = "PermissionUsageFragment"; private static final String KEY_SHOW_SYSTEM_PREFS = "_show_system"; private static final String SHOW_SYSTEM_KEY = PermissionUsageFragment.class.getName() @@ -102,8 +106,14 @@ public class PermissionUsageFragment extends PermissionsFrameFragment implements /** * @return A new fragment */ - public static @NonNull PermissionUsageFragment newInstance() { - return new PermissionUsageFragment(); + public static @NonNull PermissionUsageFragment newInstance(@Nullable String permissionName) { + PermissionUsageFragment fragment = new PermissionUsageFragment(); + Bundle arguments = new Bundle(); + if (permissionName != null) { + arguments.putString(Intent.EXTRA_PERMISSION_NAME, permissionName); + } + fragment.setArguments(arguments); + return fragment; } @Override @@ -346,6 +356,11 @@ public class PermissionUsageFragment extends PermissionsFrameFragment implements private void createPermissionSpinnerEntries() { Context context = getPreferenceManager().getContext(); + String permName = getArguments().getString(Intent.EXTRA_PERMISSION_NAME); + String groupName = Utils.getGroupOfPlatformPermission(permName); + if (permName != null && groupName == null) { + Log.w(LOG_TAG, "Invalid platform permission: " + permName); + } // Remember the selected item so we can restore it. int selectedPosition = mFilterSpinnerPermissions.getSelectedItemPosition(); @@ -374,18 +389,22 @@ public class PermissionUsageFragment extends PermissionsFrameFragment implements PermissionGroup group = filterGroups.get(i); mFilterAdapterPermissions.addFilter(new PermissionFilterItem(group, group.getLabel().toString())); + + // Use the permission group passed as an argument, if applicable. + if (group.getName().equals(groupName) && selectedPosition == -1) { + selectedLabel = group.getLabel(); + selectedPosition = mFilterAdapterPermissions.getCount() - 1; + } } // Restore the previously-selected item. if (selectedPosition == -1) { // Nothing was selected, so use the saved value. selectedPosition = mSavedPermsSpinnerIndex; - } else { - selectedPosition = mFilterAdapterPermissions.getPosition(selectedLabel); - if (selectedPosition == -1) { - // The previously-selected value no longer exists, so use the default "show all". - selectedPosition = 0; - } + } else if (!mFilterAdapterPermissions.getFilter(selectedPosition).getLabel().equals( + selectedLabel)) { + // The previously-selected value no longer exists, so use the default "show all". + selectedPosition = 0; } mFilterSpinnerPermissions.setSelection(selectedPosition); } diff --git a/src/com/android/packageinstaller/permission/utils/Utils.java b/src/com/android/packageinstaller/permission/utils/Utils.java index 85be02fd3..3dee61437 100644 --- a/src/com/android/packageinstaller/permission/utils/Utils.java +++ b/src/com/android/packageinstaller/permission/utils/Utils.java @@ -199,7 +199,7 @@ public final class Utils { * * @return The group the permission belongs to */ - private static @Nullable String getGroupOfPlatformPermission(@NonNull String permission) { + public static @Nullable String getGroupOfPlatformPermission(@NonNull String permission) { return PLATFORM_PERMISSIONS.get(permission); } -- GitLab From 4f05605e2caffe95a4e49043871507fe67e4482f Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Wed, 5 Dec 2018 13:08:04 -0800 Subject: [PATCH 169/701] Only show the foreground radio button when the app requests a background permission. Change-Id: Ifa227db312d0c5bb7d5ab528cc3fc977688f6725 Fixes: 120547658 Test: Check apps with and without background permissions. --- .../ui/handheld/AppPermissionFragment.java | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java index d29359837..36d8f88ca 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java @@ -296,6 +296,8 @@ public class AppPermissionFragment extends PermissionsFrameFragment { } private void updateButtons() { + Context context = getContext(); + // Reset everything to the "default" state: tri-state buttons are shown with exactly one // selected and no special messages. mDivider.setVisibility(View.GONE); @@ -321,8 +323,21 @@ public class AppPermissionFragment extends PermissionsFrameFragment { }); mDenyButton.setOnClickListener((v) -> requestChange(false, CHANGE_BOTH)); + // Set the allow and foreground-only button states appropriately. + if (mGroup.hasPermissionWithBackgroundMode()) { + if (mGroup.getBackgroundPermissions() == null) { + mAlwaysButton.setVisibility(View.GONE); + } else { + mForegroundOnlyButton.setVisibility(View.VISIBLE); + mAlwaysButton.setText( + context.getString(R.string.app_permission_button_allow_always)); + } + } else { + mForegroundOnlyButton.setVisibility(View.GONE); + mAlwaysButton.setText(context.getString(R.string.app_permission_button_allow)); + } + // Handle the UI for various special cases. - Context context = getContext(); if (isSystemFixed() || isPolicyFullyFixed() || isForegroundDisabledByPolicy()) { // Disable changing permissions and potentially show administrator message. mAlwaysButton.setEnabled(false); @@ -383,9 +398,7 @@ public class AppPermissionFragment extends PermissionsFrameFragment { } } else { - // The default bi-state. - mForegroundOnlyButton.setVisibility(View.GONE); - mAlwaysButton.setText(context.getString(R.string.app_permission_button_allow)); + // The default bi-state case is handled by default. } } } -- GitLab From f2fb61339c30f9a3281f5c11d65504adbe31348d Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Wed, 5 Dec 2018 14:47:40 -0800 Subject: [PATCH 170/701] Correctly sort PermissionAppsFragment when toggling system apps. My previous commit accidentally modified the behavior so that showing system apps would add them to the bottom of the list. This restores the old behavior of keeping things in sorted order. Test: Show/hide system apps, see alphabetized list. Change-Id: I1a8f65c76b92a49c7ecf427a7c8165653e21a4e4 --- .../permission/ui/handheld/PermissionAppsFragment.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java index 421653ec0..677e401e7 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java @@ -183,6 +183,9 @@ public final class PermissionAppsFragment extends PermissionsFrameFragment imple PreferenceCategory allowed = (PreferenceCategory) findPreference("allowed"); PreferenceCategory denied = (PreferenceCategory) findPreference("denied"); + allowed.setOrderingAsAdded(false); + denied.setOrderingAsAdded(false); + ArraySet preferencesToRemove = new ArraySet<>(); int numPreferences = allowed.getPreferenceCount(); for (int i = 0; i < numPreferences; i++) { -- GitLab From d7c4d7bc09b5977a8f3afeccba3bf94beb202c94 Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Tue, 4 Dec 2018 13:45:50 -0800 Subject: [PATCH 171/701] RuntimePermissionPresenter was moved ... hence use new paths Test: Looked at Settings AppInfo UI (uses RuntimePermissionPresenter) Change-Id: If7bb33a1d26f95345c319be0eb62fe1bf34c576e --- AndroidManifest.xml | 8 ++- ...RuntimePermissionPresenterServiceImpl.java | 46 +++++++++++---- ...ePermissionPresenterServiceLegacyImpl.java | 57 +++++++++++++++++++ 3 files changed, 99 insertions(+), 12 deletions(-) create mode 100644 src/com/android/packageinstaller/permission/service/RuntimePermissionPresenterServiceLegacyImpl.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index aace6dfc8..b24fd469c 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -135,9 +135,15 @@ - + + + + + + diff --git a/src/com/android/packageinstaller/permission/service/RuntimePermissionPresenterServiceImpl.java b/src/com/android/packageinstaller/permission/service/RuntimePermissionPresenterServiceImpl.java index 3f78a34ec..bd79b9797 100644 --- a/src/com/android/packageinstaller/permission/service/RuntimePermissionPresenterServiceImpl.java +++ b/src/com/android/packageinstaller/permission/service/RuntimePermissionPresenterServiceImpl.java @@ -16,10 +16,15 @@ package com.android.packageinstaller.permission.service; +import static android.content.pm.PackageManager.GET_PERMISSIONS; + +import static com.android.packageinstaller.permission.utils.Utils.shouldShowPermission; + +import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; -import android.content.pm.permission.RuntimePermissionPresentationInfo; -import android.permissionpresenterservice.RuntimePermissionPresenterService; +import android.permission.RuntimePermissionPresentationInfo; +import android.permission.RuntimePermissionPresenterService; import android.util.Log; import androidx.annotation.NonNull; @@ -29,6 +34,7 @@ import com.android.packageinstaller.permission.model.AppPermissions; import com.android.packageinstaller.permission.utils.Utils; import java.util.ArrayList; +import java.util.Collections; import java.util.List; /** @@ -38,22 +44,30 @@ public final class RuntimePermissionPresenterServiceImpl extends RuntimePermissi private static final String LOG_TAG = "PermissionPresenter"; @Override - public List onGetAppPermissions( + public @NonNull List onGetAppPermissions( @NonNull String packageName) { + return onGetAppPermissions(this, packageName); + } + + /** + * Implementation of {@link RuntimePermissionPresenterService#onGetAppPermissions(String)}}. + * Called by this class and the legacy implementation. + */ + static @NonNull List onGetAppPermissions( + @NonNull Context context, @NonNull String packageName) { final PackageInfo packageInfo; try { - packageInfo = getPackageManager().getPackageInfo(packageName, - PackageManager.GET_PERMISSIONS); + packageInfo = context.getPackageManager().getPackageInfo(packageName, GET_PERMISSIONS); } catch (PackageManager.NameNotFoundException e) { Log.e(LOG_TAG, "Error getting package:" + packageName, e); - return null; + return Collections.emptyList(); } List permissions = new ArrayList<>(); - AppPermissions appPermissions = new AppPermissions(this, packageInfo, false, null); + AppPermissions appPermissions = new AppPermissions(context, packageInfo, false, null); for (AppPermissionGroup group : appPermissions.getPermissionGroups()) { - if (Utils.shouldShowPermission(this, group)) { + if (shouldShowPermission(context, group)) { final boolean granted = group.areRuntimePermissionsGranted(); final boolean standard = Utils.OS_PKG.equals(group.getDeclaringPackage()); RuntimePermissionPresentationInfo permission = @@ -69,10 +83,20 @@ public final class RuntimePermissionPresenterServiceImpl extends RuntimePermissi @Override public void onRevokeRuntimePermission(@NonNull String packageName, @NonNull String permissionName) { + onRevokeRuntimePermission(this, packageName, permissionName); + } + + /** + * Implementation of + * {@link RuntimePermissionPresenterService#onRevokeRuntimePermission(String, String)}}. Called + * by this class and the legacy implementation. + */ + static void onRevokeRuntimePermission(@NonNull Context context, + @NonNull String packageName, @NonNull String permissionName) { try { - final PackageInfo packageInfo = getPackageManager().getPackageInfo(packageName, - PackageManager.GET_PERMISSIONS); - final AppPermissions appPermissions = new AppPermissions(this, packageInfo, false, + final PackageInfo packageInfo = context.getPackageManager().getPackageInfo(packageName, + GET_PERMISSIONS); + final AppPermissions appPermissions = new AppPermissions(context, packageInfo, false, null); final AppPermissionGroup appPermissionGroup = appPermissions.getGroupForPermission( diff --git a/src/com/android/packageinstaller/permission/service/RuntimePermissionPresenterServiceLegacyImpl.java b/src/com/android/packageinstaller/permission/service/RuntimePermissionPresenterServiceLegacyImpl.java new file mode 100644 index 000000000..2351f0371 --- /dev/null +++ b/src/com/android/packageinstaller/permission/service/RuntimePermissionPresenterServiceLegacyImpl.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.packageinstaller.permission.service; + +import android.content.pm.permission.RuntimePermissionPresentationInfo; +import android.permissionpresenterservice.RuntimePermissionPresenterService; + +import androidx.annotation.NonNull; + +import java.util.ArrayList; +import java.util.List; + +/** + * Service that provides presentation information for runtime permissions. + */ +public final class RuntimePermissionPresenterServiceLegacyImpl extends + RuntimePermissionPresenterService { + @Override + public @NonNull List onGetAppPermissions( + @NonNull String packageName) { + List permissions = + RuntimePermissionPresenterServiceImpl.onGetAppPermissions(this, packageName); + + ArrayList legacyPermissions = new ArrayList<>( + permissions.size()); + + int numPermissions = permissions.size(); + for (int i = 0; i < numPermissions; i++) { + android.permission.RuntimePermissionPresentationInfo permission = permissions.get(i); + legacyPermissions.add(new RuntimePermissionPresentationInfo(permission.getLabel(), + permission.isGranted(), permission.isStandard())); + } + + return legacyPermissions; + } + + @Override + public void onRevokeRuntimePermission(@NonNull String packageName, + @NonNull String permissionName) { + RuntimePermissionPresenterServiceImpl.onRevokeRuntimePermission(this, packageName, + permissionName); + } +} -- GitLab From 10977d88d82ea1f16c213b78b79f7b2ccf218255 Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Wed, 5 Dec 2018 14:54:56 -0800 Subject: [PATCH 172/701] Expose how many apps have a permission By calling the new API teh code makes sure the definition of "has a permission" matches the permissions controllers definition. Test: Called the method with various parameters and verified the result Bug: 120221960 Change-Id: If582c69494c2cf2fe29e4572225d71fbe6395d78 --- ...RuntimePermissionPresenterServiceImpl.java | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/src/com/android/packageinstaller/permission/service/RuntimePermissionPresenterServiceImpl.java b/src/com/android/packageinstaller/permission/service/RuntimePermissionPresenterServiceImpl.java index bd79b9797..1632cb0cd 100644 --- a/src/com/android/packageinstaller/permission/service/RuntimePermissionPresenterServiceImpl.java +++ b/src/com/android/packageinstaller/permission/service/RuntimePermissionPresenterServiceImpl.java @@ -18,6 +18,8 @@ package com.android.packageinstaller.permission.service; import static android.content.pm.PackageManager.GET_PERMISSIONS; +import static com.android.packageinstaller.permission.utils.Utils.getLauncherPackages; +import static com.android.packageinstaller.permission.utils.Utils.isSystem; import static com.android.packageinstaller.permission.utils.Utils.shouldShowPermission; import android.content.Context; @@ -25,6 +27,7 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.permission.RuntimePermissionPresentationInfo; import android.permission.RuntimePermissionPresenterService; +import android.util.ArraySet; import android.util.Log; import androidx.annotation.NonNull; @@ -109,4 +112,56 @@ public final class RuntimePermissionPresenterServiceImpl extends RuntimePermissi Log.e(LOG_TAG, "Error getting package:" + packageName, e); } } + + @Override + public int onCountPermissionApps(@NonNull List permissionNames, + boolean countOnlyGranted, boolean countSystem) { + final List pkgs = getPackageManager().getInstalledPackages(GET_PERMISSIONS); + final ArraySet launcherPkgs = getLauncherPackages(this); + + int numApps = 0; + + final int numPkgs = pkgs.size(); + for (int pkgNum = 0; pkgNum < numPkgs; pkgNum++) { + final PackageInfo pkg = pkgs.get(pkgNum); + + if (!countSystem && isSystem(pkg.applicationInfo, launcherPkgs)) { + continue; + } + + final int numPerms = permissionNames.size(); + for (int permNum = 0; permNum < numPerms; permNum++) { + final String perm = permissionNames.get(permNum); + + final AppPermissionGroup group = AppPermissionGroup.create(this, pkg, + permissionNames.get(permNum), true); + if (group == null || !shouldShowPermission(this, group)) { + continue; + } + + AppPermissionGroup subGroup = null; + if (group.hasPermission(perm)) { + subGroup = group; + } else { + AppPermissionGroup bgGroup = group.getBackgroundPermissions(); + if (bgGroup != null && bgGroup.hasPermission(perm)) { + subGroup = group; + } + } + + if (subGroup != null) { + if (!countOnlyGranted || subGroup.areRuntimePermissionsGranted()) { + // The permission might not be granted, but some permissions of the group + // are granted. In this case the permission is granted silently when the app + // asks for it. + // Hence this is as-good-as-granted and we count it. + numApps++; + break; + } + } + } + } + + return numApps; + } } -- GitLab From 641b8aed11159c6817765681311622b263c6966e Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Mon, 12 Nov 2018 15:17:14 -0800 Subject: [PATCH 173/701] Add historical app op usage information to the app permission usage screen. This adds historical app op usage information to the screen that reviews an app's usage of its permissions. Bug: 63532550 Test: Open this screen. Change-Id: I2661f903beae327c717a506d2d1575d12ed30c18 --- res/values/strings.xml | 7 ++- .../handheld/AppPermissionUsageFragment.java | 53 +++++++++++++++++-- 2 files changed, 53 insertions(+), 7 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index b351d2e60..ca24d9e4d 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -270,8 +270,11 @@ App permissions usage - - %1$s ago + + Access: %1$s times. Total duration: %2$s. Last used %3$s ago. + + + Access: %1$s times. Last used %2$s ago. Allow diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java index 6783c610c..d1ee3927b 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java @@ -18,6 +18,7 @@ package com.android.packageinstaller.permission.ui.handheld; import android.app.ActionBar; import android.app.Activity; +import android.app.AppOpsManager; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; @@ -41,6 +42,7 @@ import androidx.preference.PreferenceScreen; import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.model.AppPermissionUsage; import com.android.packageinstaller.permission.model.AppPermissions; +import com.android.packageinstaller.permission.model.Permission; import com.android.packageinstaller.permission.utils.IconDrawableFactory; import com.android.packageinstaller.permission.utils.Utils; import com.android.permissioncontroller.R; @@ -61,6 +63,8 @@ public class AppPermissionUsageFragment extends SettingsWithHeader { private static final String LOG_TAG = "AppPermissionUsageFragment"; + private @NonNull AppOpsManager mAppOpsManager; + private @NonNull AppPermissions mAppPermissions; /** @@ -103,6 +107,7 @@ public class AppPermissionUsageFragment extends SettingsWithHeader { } mAppPermissions = new AppPermissions(activity, packageInfo, false, () -> getActivity().finish()); + mAppOpsManager = (AppOpsManager) getContext().getSystemService(AppOpsManager.class); addPreferences(); } @@ -154,6 +159,9 @@ public class AppPermissionUsageFragment extends SettingsWithHeader { // Find the permission usages we want to add. List usages = new ArrayList<>(); Map usageToGroup = new ArrayMap<>(); + Map groupToHistory = + new ArrayMap<>(); + PackageInfo packageInfo = mAppPermissions.getPackageInfo(); List permissionGroups = mAppPermissions.getPermissionGroups(); int numGroups = permissionGroups.size(); for (int groupNum = 0; groupNum < numGroups; groupNum++) { @@ -179,25 +187,60 @@ public class AppPermissionUsageFragment extends SettingsWithHeader { usages.add(usage); usageToGroup.put(usage, group); } + + ArrayList permissions = group.getPermissions(); + ArrayList permissionNames = new ArrayList<>(); + for (int i = 0; i < permissions.size(); i++) { + String opName = AppOpsManager.permissionToOp(permissions.get(i).getName()); + if (opName != null) { + permissionNames.add(opName); + } + } + long curTime = System.currentTimeMillis(); + groupToHistory.put(group, + mAppOpsManager.getHistoricalPackagesOps(packageInfo.applicationInfo.uid, + packageInfo.packageName, + permissionNames.toArray(new String[permissionNames.size()]), + curTime - 1000 * 60 * 60 * 24, curTime)); } // Add the permission usages. usages.sort(Comparator.comparing(AppPermissionUsage::getTime).reversed()); Set addedEntries = new ArraySet<>(); int numUsages = usages.size(); - for (int i = 0; i < numUsages; i++) { - AppPermissionUsage usage = usages.get(i); - AppPermissionGroup group = usageToGroup.get(usage); + for (int usageNum = 0; usageNum < numUsages; usageNum++) { + AppPermissionUsage usage = usages.get(usageNum); // Filter out entries we've seen before. if (!addedEntries.add(usage.getPackageName() + "," + usage.getPermissionGroupName())) { continue; } + AppPermissionGroup group = usageToGroup.get(usage); + + AppOpsManager.HistoricalPackageOps history = groupToHistory.get(group); + long numAccesses = 0; + long totalDuration = 0; + for (int i = 0; i < history.getEntryCount(); i++) { + AppOpsManager.HistoricalOpEntry historyEntry = history.getEntryAt(i); + numAccesses += historyEntry.getForegroundAccessCount() + + historyEntry.getBackgroundAccessCount(); + totalDuration += historyEntry.getForegroundAccessDuration() + + historyEntry.getBackgroundAccessDuration(); + } + Preference pref = new PermissionUsagePreference(context, group); pref.setTitle(usage.getPermissionGroupLabel()); long timeDiff = System.currentTimeMillis() - usage.getTime(); - String timeDiffStr = Utils.getTimeDiffStr(context, timeDiff); - pref.setSummary(context.getString(R.string.app_permission_usage_summary, timeDiffStr)); + if (totalDuration == 0) { + pref.setSummary( + context.getString(R.string.app_permission_usage_summary_no_duration, + numAccesses, Utils.getTimeDiffStr(context, timeDiff))); + } else { + pref.setSummary( + context.getString(R.string.app_permission_usage_summary, numAccesses, + Utils.getTimeDiffStr(context, totalDuration), + Utils.getTimeDiffStr(context, timeDiff))); + } pref.setIcon(Utils.applyTint(context, group.getIconResId(), android.R.attr.colorControlNormal)); pref.setKey(usage.getPackageName() + "," + usage.getPermissionGroupName()); -- GitLab From bec00287aa2d66c0f8f7e5cc67dc4e33695b8f67 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Thu, 6 Dec 2018 05:41:12 -0800 Subject: [PATCH 174/701] Import translations. DO NOT MERGE Change-Id: I0af16988f4ff3634236cbf05cce44f2be7267a5a Auto-generated-cl: translation import --- res/values-af/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-am/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-ar/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-as/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-az/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-b+sr+Latn/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-be/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-bg/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-bn/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-bs/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-ca/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-cs/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-da/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-de/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-el/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-en-rAU/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-en-rCA/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-en-rGB/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-en-rIN/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-en-rXC/strings.xml | 40 ++++++++++++++++++++++ res/values-es-rUS/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-es/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-et/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-eu/strings.xml | 43 ++++++++++++++++++++++++ res/values-fa/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-fi/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-fr-rCA/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-fr/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-gl/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-gu/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-hi/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-hr/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-hu/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-hy/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-in/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-is/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-it/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-iw/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-ja/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-ka/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-kk/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-km/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-kn/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-ko/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-ky/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-lo/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-lt/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-lv/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-mk/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-ml/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-mn/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-mr/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-ms/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-my/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-nb/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-ne/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-nl/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-or/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-pa/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-pl/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-pt-rBR/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-pt-rPT/strings.xml | 43 ++++++++++++++++++++++++ res/values-pt/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-ro/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-ru/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-si/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-sk/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-sl/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-sq/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-sr/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-sv/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-sw/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-ta/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-te/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-th/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-tl/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-tr/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-uk/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-ur/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-uz/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-vi/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-zh-rCN/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-zh-rHK/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-zh-rTW/strings.xml | 57 ++++++++++++++++++++++++++++++++ res/values-zu/strings.xml | 57 ++++++++++++++++++++++++++++++++ 85 files changed, 4800 insertions(+) diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml index ec4e60396..8bd6a34f0 100644 --- a/res/values-af/strings.xml +++ b/res/values-af/strings.xml @@ -61,6 +61,7 @@ "Admin het agtergrondtoegang gedeaktiveer" "Admin het agtergrondtoegang geaktiveer" "Admin het voorgrondtoegang geaktiveer" + "Toestemming gestel deur stelsel" @@ -95,6 +96,22 @@ "Geen toestemminggebruike nie" "Programtoestemmingsgebruik" "%1$s gelede" + "Laat toe" + "Laat altyd toe" + "Laat net toe terwyl die program gebruik word" + "Weier" + "%1$s-toestemming" + "%1$s-toegang vir %2$s" + "%1$s het %3$s gelede toegang tot jou %2$s verkry." + + + "Bekyk gedetailleerde toestemmingsgebruik" + + + + + + %s dae 1 dag @@ -111,4 +128,44 @@ %s sekondes 1 sekonde + "Gebruik <b>%1$s</b> as jou %2$s?" + "Gebruik <b>%1$s</b> pleks van <b>%1$s</b> as jou %2$s?" + + + + + + + + + + + "Foonprogram" + "SMS-program" + "Blaaierprogram" + "Galeryprogram" + "Musiekprogram" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml index fc60af44b..d84f7ce5b 100644 --- a/res/values-am/strings.xml +++ b/res/values-am/strings.xml @@ -61,6 +61,7 @@ "የዳራ መዳረሻ በአስተዳዳሪ ተሰናክሏል" "የዳራ መዳረሻ በአስተዳዳሪ ነቅቷል" "የፊት መዳረሻ በአስተዳዳሪ ነቅቷል" + "ፈቃድ በሥርዓት ተቀናብሯል" @@ -95,6 +96,22 @@ "ምንም ፈቃድ አጠቃቀሞች የሉም" "የመተግበሪያ ፈቃዶች አጠቃቀም" "ከ%1$s በፊት" + "ፍቀድ" + "ሁልጊዜ ፍቀድ" + "መተግበሪያው ጥቅም ላይ እያለ ብቻ ፍቀድ" + "ከልክል" + "የ%1$s ፈቃድ" + "ለ%2$s%1$s መዳረሻ" + "%1$s%3$s በፊት የእርስዎን %2$s ደርሶ ነበር።" + + + "ዝርዝር የፈቃዶች አጠቃቀምን ይመልከቱ" + + + + + + %s ቀኖች %s ቀኖች @@ -111,4 +128,44 @@ %s ሰከንዶች %s ሰከንዶች + "<b>%1$s</b>ን እንደ የእርስዎ %2$s ይጠቀሙበት?" + "ከ<b>%1$s</b> ይልቅ <b>%1$s</b>ን እንደ የእርስዎ %2$s ይጠቀሙበት?" + + + + + + + + + + + "የስልክ መተግበሪያ" + "የኤስኤምኤስ መተግበሪያ" + "የአሳሽ መተግበሪያ" + "የማዕከለ ሥዕላት መተግበሪያ" + "የሙዚቃ መተግበሪያ" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml index 3b1c25b21..351c7fa10 100644 --- a/res/values-ar/strings.xml +++ b/res/values-ar/strings.xml @@ -65,6 +65,7 @@ "أوقف المشرف وصول التطبيق للبيانات أثناء عدم نشاطه." "فعَّل المشرف وصول التطبيق للبيانات أثناء عدم نشاطه." "فعَّل المشرف وصول التطبيق للبيانات أثناء نشاطه." + "تم ضبط الإذن بواسطة النظام." @@ -99,6 +100,22 @@ "لم يتمّ استخدام الأذونات" "استخدام أذونات التطبيق" "قبل %1$s" + "سماح" + "السماح طوال الوقت" + "السماح فقط أثناء استخدام التطبيق" + "رفض" + "إذن %1$s" + "إذن %1$s الممنوح للتطبيق %2$s" + "قبل %3$s، استخدَم تطبيق %1$s إذن %2$s الذي منحته." + + + "عرض تفاصيل استخدام الأذونات" + + + + + + %s يوم يومان (%s) @@ -131,4 +148,44 @@ %s ثانية ثانية واحدة + "‏هل تريد الاستفادة من <b>%1$s</b> في دور %2$s؟" + "‏هل تريد الاستفادة من <b>%1$s</b> بدلاً من <b>%1$s</b> في دور %2$s؟" + + + + + + + + + + + "تطبيق الهاتف" + "‏تطبيق SMS" + "تطبيق المتصفّح" + "تطبيق المعرض" + "تطبيق الموسيقى" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml index 04c25fe61..5f045475a 100644 --- a/res/values-as/strings.xml +++ b/res/values-as/strings.xml @@ -61,6 +61,7 @@ "প্ৰশাসকে নেপথ্যৰ এক্সেছ অক্ষম কৰি ৰাখিছে" "প্ৰশাসকে নেপথ্যৰ এক্সেছ সক্ষম কৰি ৰাখিছে" "প্ৰশাসকে অগ্ৰভূমিৰ এক্সেছ সক্ষম কৰি ৰাখিছে" + "ছিষ্টেমে অনুমতি ছেট কৰিছে" @@ -95,6 +96,22 @@ "অনুমতি ব্যৱহাৰ কৰা হোৱা নাই" "এপৰ অনুমতিৰ ব্যৱহাৰ" "%1$s আগত" + "অনুমতি দিয়ক" + "সকলো সময়ৰ বাবে অনুমতি দিয়ক" + "কেৱল এপটো ব্যৱহাৰ হৈ থকা সময়ত অনুমতি দিয়ক" + "অস্বীকাৰ কৰক" + "%1$s অনুমতি" + "%2$s%1$s এক্সেছ" + "%1$sএ আপোনাৰ %2$s%3$s পূর্বে এক্সেছ পাইছিল।" + + + "অনুমতিৰ ব্যৱহাৰৰ সবিশেষ চাওক" + + + + + + %s দিন %s দিন @@ -111,4 +128,44 @@ %s ছেকেণ্ড %s ছেকেণ্ড + "<b>%1$s</b>ক আপোনাৰ %2$sহিচাপে ব্যৱহাৰ কৰিবনে?" + "<b>%1$s</b>ৰ পৰিৱৰ্তে <b>%1$s</b>ক আপোনাৰ %2$sহিচাপে ব্যৱহাৰ কৰিবনে?" + + + + + + + + + + + "ফ\'ন এপ্" + "এছএমএছ এপ্" + "ব্ৰাউজাৰ এপ্" + "Gallery এপ্" + "Music এপ্‌" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml index e9c2f2c28..6c813b848 100644 --- a/res/values-az/strings.xml +++ b/res/values-az/strings.xml @@ -61,6 +61,7 @@ "Arxa fon girişi admin tərəfindən deaktiv edildi" "Arxa fon girişi admin tərəfindən aktiv edildi" "Ön fon girişi admin tərəfindən aktiv edildi" + "Sistemin təyin etdiyi icazə" @@ -95,6 +96,22 @@ "İcazələrdən istifadə olunmayıb" "Tətbiq icazələri istifadəsi" "%1$s əvvəl" + "İcazə verin" + "Həmişə icazə verin" + "Yalnız tətbiqin istifadəsi zamanı icazə verin" + "İmtina edin" + "%1$s üçün icazə" + "%2$s üçün %1$s girişi" + "%1$s %2$s adlı məkana %3$s əvvəl daxil oldu." + + + "İcazələrin istifadəsi ilə bağlı ətraflı məlumata baxın" + + + + + + %s gün 1 gün @@ -111,4 +128,44 @@ %s saniyə 1 saniyə + "<b>%1$s</b> tətbiqi %2$s olaraq istifadə edilsin?" + "<b>%1$s</b> tətbiqinin əvəzinə <b>%1$s</b> %2$s olaraq istifadə edilsin?" + + + + + + + + + + + "Telefon tətbiqi" + "SMS tətbiqi" + "Brauzer tətbiqi" + "Qalereya tətbiqi" + "Musiqi tətbiqi" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml index 930587d21..3fb963499 100644 --- a/res/values-b+sr+Latn/strings.xml +++ b/res/values-b+sr+Latn/strings.xml @@ -62,6 +62,7 @@ "Administrator je onemogućio pristup u pozadini" "Administrator je omogućio pristup u pozadini" "Administrator je omogućio pristup u prvom planu" + "Sistem je podesio dozvolu" @@ -96,6 +97,22 @@ "Dozvole nisu korišćene" "Korišćenje dozvola za aplik." "pre %1$s" + "Dozvoli" + "Dozvoli uvek" + "Dozvoli samo dok se aplikacija koristi" + "Odbij" + "Dozvola %1$s" + "Pristup dozvoli %1$s za aplikaciju %2$s" + "Aplikacija %1$s je pristupila dozvoli %2$s pre %3$s." + + + "Pregledajte detaljne dozvole za korišćenje" + + + + + + %s dan %s dana @@ -116,4 +133,44 @@ %s sekunde %s sekundi + "Želite li da <b>%1$s</b> bude %2$s?" + "Želite li da <b>%1$s</b> bude %2$s umesto <b>%1$s</b>?" + + + + + + + + + + + "Aplikacija Telefon" + "Aplikacija za SMS" + "Aplikacija pregledača" + "Aplikacija Galerija" + "Aplikacija Muzika" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml index 30487d8e9..9f90bb784 100644 --- a/res/values-be/strings.xml +++ b/res/values-be/strings.xml @@ -63,6 +63,7 @@ "Адміністратар адключыў доступ у фонавым рэжыме" "Адміністратар уключыў доступ у фонавым рэжыме" "Адміністратар уключыў доступ у актыўным рэжыме" + "Дазвол дадзены сістэмай" @@ -97,6 +98,22 @@ "Без выкарыстання дазволаў" "Выкарыстанне дазволаў праграмы" "%1$s таму назад" + "Дазволіць" + "Дазволіць у любым рэжыме" + "Дазволіць толькі ў актыўным рэжыме праграмы" + "Адмовіць" + "Дазвол \"%1$s\"" + "Доступ да дазволу \"%1$s\" для праграмы \"%2$s\"" + "Праграма \"%1$s\" атрымала доступ да дазволу \"%2$s\" %3$s таму назад." + + + "Прагледзець звесткі пра выкарыстанне дазволаў" + + + + + + %s дзень %s дні @@ -121,4 +138,44 @@ %s секунд %s секунды + "Выкарыстоўваць праграму <b>%1$s</b> як %2$s?" + "Выкарыстоўваць праграму <b>%1$s</b> замест праграмы <b>%1$s</b> як %2$s?" + + + + + + + + + + + "Праграма \"Тэлефон\"" + "Праграма для SMS" + "Браўзер" + "Праграма \"Галерэя\"" + "Праграма \"Музыка\"" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml index db2f4b92f..c29e7b180 100644 --- a/res/values-bg/strings.xml +++ b/res/values-bg/strings.xml @@ -61,6 +61,7 @@ "Достъпът на заден план е деактивиран от администратора" "Достъпът на заден план е активиран от администратора" "Достъпът на преден план е активиран от администратора" + "Разрешението е зададено от системата" @@ -95,6 +96,22 @@ "Разрешенията не са използвани" "Използване на разрешенията" "Преди %1$s" + "Разрешаване" + "Разрешаване във всички случаи" + "Разрешаване само докато приложението се използва" + "Отказ" + "Разрешение за %1$s" + "Достъп до %1$s за %2$s" + "%1$s осъществи достъп до %2$s ви преди %3$s." + + + "Преглед на подробности за използването на разрешенията" + + + + + + %s дни 1 ден @@ -111,4 +128,44 @@ %s секунди 1 секунда + "Да се използва ли <b>%1$s</b> като %2$s?" + "Да се използва ли <b>%1$s</b> вместо <b>%1$s</b> като %2$s?" + + + + + + + + + + + "Приложение за телефон" + "Приложение за SMS" + "Приложение за браузър" + "Приложение за галерия" + "Приложение за музика" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml index 68483925f..a626c0a15 100644 --- a/res/values-bn/strings.xml +++ b/res/values-bn/strings.xml @@ -61,6 +61,7 @@ "অ্যাডমিন ব্যাকগ্রাউন্ড অ্যাক্সেস বন্ধ করেছেন" "অ্যাডমিন ব্যাকগ্রাউন্ড অ্যাক্সেস চালু করেছেন" "অ্যাডমিন ফোরগ্রাউন্ড অ্যাক্সেস চালু করেছেন" + "সিস্টেমের মাধ্যমে সেট করা অনুমতি" @@ -95,6 +96,22 @@ "কোন অনুমতির ব্যবহার হয়নি" "অ্যাপের অনুমতির ব্যবহার" "%1$s আগে" + "অনুমতি দিন" + "সব সময়ের অনুমতি দিন" + "অ্যাপ ব্যবহারের সময়ই শুধুমাত্র অনুমতি দিন" + "খারিজ করুন" + "%1$s অনুমতি" + "%2$s-এর জন্য %1$s" + "আপনার %2$s %3$s আগে %1$s অ্যাক্সেস করা হয়েছে।" + + + "বিস্তারিত অনুমতির ব্যবহার দেখুন" + + + + + + %s দিন %s দিন @@ -111,4 +128,44 @@ %s সেকেন্ড %s সেকেন্ড + "আপনার %2$s হিসেবে <b>%1$s</b> ব্যবহার করতে চান?" + "আপনার %2$s হিসেবে; <b>%1$s</b>-এর পরিবর্তে <b>%1$s</b> ব্যবহার করতে চান?" + + + + + + + + + + + "ফোন অ্যাপ" + "এসএমএস অ্যাপ" + "ব্রাউজার অ্যাপ" + "গ্যালারি অ্যাপ" + "মিউজিক অ্যাপ" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml index 782990945..d2a3e6f64 100644 --- a/res/values-bs/strings.xml +++ b/res/values-bs/strings.xml @@ -62,6 +62,7 @@ "Administrator je onemogućio pristup iz pozadine" "Administrator je omogućio pristup iz pozadine" "Administrator je omogućio pristup iz prvog plana" + "Sistem je poslao odobrenje" @@ -96,6 +97,22 @@ "Odobrenje nije upotrijebljeno" "Korišt. dozvole za aplikacije" "Prije %1$s" + "Dozvoli" + "Dozvoli svaki put" + "Dozvoli samo kada se aplikacija koristi" + "Odbij" + "Odobrenje %1$s" + "Pristup odobrenju %1$s za aplikaciju %2$s" + "Aplikacija %1$s je pristupila odobrenju %2$s prije %3$s." + + + "Vidi detaljno korištenje odobrenja" + + + + + + %s dan %s dana @@ -116,4 +133,44 @@ %s sekunde %s sekundi + "Koristiti aplikaciju <b>%1$s</b> kao %2$s?" + "Koristiti aplikaciju <b>%1$s</b> umjesto <b>%1$s</b> kao %2$s?" + + + + + + + + + + + "Aplikacija Telefon" + "Aplikacija za SMS" + "Aplikacija preglednika" + "Aplikacija galerije" + "Aplikacija za muziku" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml index 1625c1b1a..11d067acf 100644 --- a/res/values-ca/strings.xml +++ b/res/values-ca/strings.xml @@ -61,6 +61,7 @@ "L\'administrador ha desactivat l\'accés en segon pla" "L\'administrador ha activat l\'accés en segon pla" "L\'administrador ha activat l\'accés en primer pla" + "Permís definit pel sistema" @@ -95,6 +96,22 @@ "Cap ús de permisos" "Ús de permisos de l\'aplicació" "Fa %1$s" + "Permet" + "Permet sempre" + "Permet només mentre s\'utilitza l\'aplicació" + "Denega" + "Permís per accedir a %1$s" + "Accés de l\'aplicació %2$s a %1$s" + "%1$s va accedir fa %3$s a %2$s." + + + "Mostra dades detallades sobre l\'ús de permisos" + + + + + + %s dies 1 dia @@ -111,4 +128,44 @@ %s segons 1 segon + "Vols utilitzar <b>%1$s</b> com a %2$s?" + "Vols utilitzar <b>%1$s</b> en lloc de l\'aplicació <b>%1$s</b> com a %2$s?" + + + + + + + + + + + "Aplicació Telèfon" + "Aplicació d\'SMS" + "Aplicació de navegador" + "Aplicació Galeria" + "Aplicació Música" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml index 4376d9049..4e44fe91b 100644 --- a/res/values-cs/strings.xml +++ b/res/values-cs/strings.xml @@ -63,6 +63,7 @@ "Přístup na pozadí byl zakázán administrátorem" "Přístup na pozadí byl povolen administrátorem" "Přístup na popředí byl povolen administrátorem" + "Oprávnění nastavená systémem" @@ -97,6 +98,22 @@ "Žádné využití oprávnění" "Využití oprávnění aplikace" "Před %1$s" + "Povolit" + "Povolit vždy" + "Povolit jen během používání aplikace" + "Zakázat" + "Oprávnění %1$s" + "Přístup k údajům %1$s pro aplikaci %2$s" + "Aplikace %1$s získala před %3$s přístup k těmto údajům: %2$s." + + + "Zobrazit podrobné využití oprávnění" + + + + + + %s dny %s dne @@ -121,4 +138,44 @@ %s sekund 1 sekunda + "Použít aplikaci <b>%1$s</b> jako %2$s?" + "Použít aplikaci <b>%1$s</b> namísto aplikace <b>%1$s</b> jako %2$s?" + + + + + + + + + + + "Aplikace Telefon" + "Aplikace pro SMS" + "Prohlížeč" + "Aplikace Galerie" + "Aplikace Hudba" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml index 3004a7733..3aaef14bd 100644 --- a/res/values-da/strings.xml +++ b/res/values-da/strings.xml @@ -61,6 +61,7 @@ "Adgang i baggrunden er deaktiveret af en administrator" "Adgang i baggrunden er aktiveret af en administrator" "Adgang i forgrunden er aktiveret af en administrator" + "Tilladelsen er indstillet af systemet" @@ -95,6 +96,22 @@ "Ingen brug af tilladelsen" "Brug af apptilladelser" "For %1$s siden" + "Tillad" + "Tillad altid" + "Tillad kun, mens appen bruges" + "Afvis" + "Tilladelse for %1$s" + "Adgang til %1$s for %2$s" + "%1$s anvendte din/dit %2$s for %3$s siden." + + + "Se detaljeret brug af tilladelser" + + + + + + %s dag %s dage @@ -111,4 +128,44 @@ %s sekund %s sekunder + "Vil du bruge <b>%1$s</b> som din %2$s?" + "Vil du bruge <b>%1$s</b> i stedet for <b>%1$s</b> som din %2$s?" + + + + + + + + + + + "Appen Opkald" + "Sms-app" + "Browserapp" + "Galleriapp" + "Musikapp" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index a6e65fdd6..0909cb319 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -61,6 +61,7 @@ "Hintergrundzugriff vom Administrator deaktiviert" "Hintergrundzugriff vom Administrator aktiviert" "Vordergrundzugriff vom Administrator aktiviert" + "Berechtigung vom System festgelegt" @@ -95,6 +96,22 @@ "Keine Berechtigungen verwendet" "Nutzung von App-Berechtigungen" "vor %1$s" + "Zulassen" + "Immer zulassen" + "Nur zulassen, wenn die App verwendet wird" + "Nicht zulassen" + "Berechtigung \"%1$s\"" + "Zugriff auf %1$s für %2$s" + "%1$s hat vor %3$s auf %2$s zugegriffen." + + + "Details zur Berechtigungsnutzung ansehen" + + + + + + %s Tage 1 Tag @@ -111,4 +128,44 @@ %s Sekunden 1 Sekunde + "<b>%1$s</b> als %2$s verwenden?" + "<b>%1$s</b> anstelle von <b>%1$s</b> als %2$s verwenden?" + + + + + + + + + + + "Telefon-App" + "SMS-App" + "Browser-App" + "Galerie App" + "Musik App" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml index 3f0a47264..ff40d3017 100644 --- a/res/values-el/strings.xml +++ b/res/values-el/strings.xml @@ -61,6 +61,7 @@ "Η πρόσβαση στο παρασκήνιο απενεργοποιήθ. από τον διαχειριστή" "Η πρόσβαση στο παρασκήνιο ενεργοποιήθηκε από τον διαχειριστή" "Η πρόσβαση στο προσκήνιο ενεργοποιήθηκε από τον διαχειριστή" + "Η άδεια ορίστηκε από το σύστημα" @@ -95,6 +96,22 @@ "Καμία χρήση δικαιωμάτων" "Χρήση αδειών εφαρμογής" "%1$s πριν" + "Να επιτρέπεται" + "Να επιτρέπεται πάντα" + "Να επιτρέπεται μόνο όταν χρησιμοποιείται η εφαρμογή" + "Να μην επιτρέπεται" + "Άδεια %1$s" + "Πρόσβαση σε %1$s για την εφαρμογή %2$s" + "Η εφαρμογή %1$s είχε πρόσβαση σε %2$s πριν από %3$s." + + + "Προβολή λεπτομερούς χρήσης αδειών" + + + + + + %s ημέρες 1 ημέρα @@ -111,4 +128,44 @@ %s δευτερόλεπτα 1 δευτερόλεπτο + "Χρήση εφαρμογής <b>%1$s</b> ως %2$s;" + "Χρήση εφαρμογής <b>%1$s</b> αντί για <b>%1$s</b> ως %2$s;" + + + + + + + + + + + "Εφαρμογή \"Τηλέφωνο\"" + "Εφαρμογή SMS" + "Εφαρμ. προγράμματος περιήγησης" + "Εφαρμογή Gallery" + "Εφαρμογή μουσικής" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml index d79ad9e46..f23a94f7e 100644 --- a/res/values-en-rAU/strings.xml +++ b/res/values-en-rAU/strings.xml @@ -61,6 +61,7 @@ "Background access disabled by admin" "Background access enabled by admin" "Foreground access enabled by admin" + "Permission set by system" @@ -95,6 +96,22 @@ "No permission usages" "App permissions usage" "%1$s ago" + "Allow" + "Allow all the time" + "Allow only while the app is in use" + "Deny" + "%1$s permission" + "%1$s access for %2$s" + "%1$s accessed your %2$s %3$s ago." + + + "View detailed permissions usage" + + + + + + %s days 1 day @@ -111,4 +128,44 @@ %s seconds 1 second + "Use <b>%1$s</b> as your %2$s?" + "Use <b>%1$s</b> instead of <b>%1$s</b> as your %2$s?" + + + + + + + + + + + "Phone app" + "SMS app" + "Browser app" + "Gallery app" + "Music app" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml index d79ad9e46..f23a94f7e 100644 --- a/res/values-en-rCA/strings.xml +++ b/res/values-en-rCA/strings.xml @@ -61,6 +61,7 @@ "Background access disabled by admin" "Background access enabled by admin" "Foreground access enabled by admin" + "Permission set by system" @@ -95,6 +96,22 @@ "No permission usages" "App permissions usage" "%1$s ago" + "Allow" + "Allow all the time" + "Allow only while the app is in use" + "Deny" + "%1$s permission" + "%1$s access for %2$s" + "%1$s accessed your %2$s %3$s ago." + + + "View detailed permissions usage" + + + + + + %s days 1 day @@ -111,4 +128,44 @@ %s seconds 1 second + "Use <b>%1$s</b> as your %2$s?" + "Use <b>%1$s</b> instead of <b>%1$s</b> as your %2$s?" + + + + + + + + + + + "Phone app" + "SMS app" + "Browser app" + "Gallery app" + "Music app" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml index d79ad9e46..f23a94f7e 100644 --- a/res/values-en-rGB/strings.xml +++ b/res/values-en-rGB/strings.xml @@ -61,6 +61,7 @@ "Background access disabled by admin" "Background access enabled by admin" "Foreground access enabled by admin" + "Permission set by system" @@ -95,6 +96,22 @@ "No permission usages" "App permissions usage" "%1$s ago" + "Allow" + "Allow all the time" + "Allow only while the app is in use" + "Deny" + "%1$s permission" + "%1$s access for %2$s" + "%1$s accessed your %2$s %3$s ago." + + + "View detailed permissions usage" + + + + + + %s days 1 day @@ -111,4 +128,44 @@ %s seconds 1 second + "Use <b>%1$s</b> as your %2$s?" + "Use <b>%1$s</b> instead of <b>%1$s</b> as your %2$s?" + + + + + + + + + + + "Phone app" + "SMS app" + "Browser app" + "Gallery app" + "Music app" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml index d79ad9e46..f23a94f7e 100644 --- a/res/values-en-rIN/strings.xml +++ b/res/values-en-rIN/strings.xml @@ -61,6 +61,7 @@ "Background access disabled by admin" "Background access enabled by admin" "Foreground access enabled by admin" + "Permission set by system" @@ -95,6 +96,22 @@ "No permission usages" "App permissions usage" "%1$s ago" + "Allow" + "Allow all the time" + "Allow only while the app is in use" + "Deny" + "%1$s permission" + "%1$s access for %2$s" + "%1$s accessed your %2$s %3$s ago." + + + "View detailed permissions usage" + + + + + + %s days 1 day @@ -111,4 +128,44 @@ %s seconds 1 second + "Use <b>%1$s</b> as your %2$s?" + "Use <b>%1$s</b> instead of <b>%1$s</b> as your %2$s?" + + + + + + + + + + + "Phone app" + "SMS app" + "Browser app" + "Gallery app" + "Music app" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-en-rXC/strings.xml b/res/values-en-rXC/strings.xml index 2beaa76c0..869697313 100644 --- a/res/values-en-rXC/strings.xml +++ b/res/values-en-rXC/strings.xml @@ -61,6 +61,7 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‏‏‎‏‏‎‎‎‏‏‎‎‏‎‎‏‏‏‎‏‎‏‎‎‎‏‏‏‏‎‏‎‎‎‎‎‏‎‎‏‏‏‏‎‏‎‏‏‎‎‏‏‎‏‎‏‎‎Background access disabled by admin‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‎‎‏‏‎‏‎‏‎‎‏‎‏‎‏‏‏‎‎‎‎‏‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‏‎‎‎‏‏‎‏‎‏‏‎‏‏‎‏‎‏‎Background access enabled by admin‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‎‎‎‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‏‎‎‎‏‎‏‏‎‏‏‏‏‎‏‎‎‏‏‎‎‎‏‏‏‏‏‎‎Foreground access enabled by admin‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‏‏‎‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‏‎‎‎‎‏‏‎‏‏‎‎‎‏‏‎Permission set by system‎‏‎‎‏‎" @@ -95,6 +96,18 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‏‎‏‏‎‎‏‎‏‏‎‏‏‎‎‎‎‎‏‏‏‎‎‎‎‏‎‎‎‎‏‏‎‏‏‏‎‏‎‏‎‎‏‏‎‏‏‎‏‏‎‏‏‎‏‏‎No permission usages‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‏‎‎‎‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‏‏‎‏‎‏‎‎‏‏‎‎‎‏‏‎‎‏‏‏‎‏‎‏‎‏‎‎‏‏‏‏‎‎App permissions usage‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‏‎‎‏‏‏‎‎‎‏‎‏‎‎‎‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‏‎‎‎‏‏‏‎‎‏‎‏‏‎‎‏‏‎‎‎‏‎‏‏‏‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ ago‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‏‏‎‏‏‎‏‏‎‏‏‏‏‏‎‏‎‎‏‎‎‎‎‎‏‏‏‎‎‏‏‎‎‎‏‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‎Allow‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‏‏‎‏‏‏‎‎‏‎‏‎‏‏‏‎‎‎‎‏‎‏‎‎‏‎‏‎‏‎‎‎‏‎‎‏‎‏‏‎‎‏‏‏‏‎‏‏‎‏‏‏‏‏‎‎‎Allow all the time‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‏‎‏‏‎‎‏‎‏‎‏‏‏‎‏‎‏‏‎‎‎‎‎‏‎‎‏‎‎‏‎‎‎‏‎‏‎‏‎‎‎‎‎‎‎‎‎‎‎‎‎‏‏‎‏‎Allow only while the app is in use‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‎‏‎‏‎‎‏‎‎‏‏‏‏‎‏‎‏‏‏‏‏‎‏‎‏‎‎‎‏‎‏‎‏‏‎‎‏‏‎‏‎‏‎‏‎‎‎‏‎‎‏‎‎‎‎Deny‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‎‎‎‎‏‎‏‎‏‏‎‎‏‏‏‎‏‎‎‎‏‏‎‎‏‎‏‎‏‏‏‎‎‎‏‎‎‏‎‎‏‏‏‎‎‎‎‏‏‏‏‎‎‎‎‏‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ permission‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‎‏‎‏‎‏‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‎‎‎‎‎‎‎‏‏‎‏‎‎‎‏‎‎‎‏‏‏‎‏‏‎‏‎‏‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ access for ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‎‏‏‏‎‏‏‏‎‏‏‎‎‎‏‎‎‏‎‏‏‏‏‏‏‏‎‏‏‎‎‏‏‏‎‎‎‏‏‎‏‎‏‎‎‏‏‎‎‏‏‏‎‎‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ accessed your ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎ ‎‏‎‎‏‏‎%3$s‎‏‎‎‏‏‏‎ ago.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‏‎‏‏‏‏‏‏‎‎‏‏‎‎‎‏‏‎‎‎‏‏‏‎‏‏‎‏‏‏‏‎‏‏‎‎‏‏‎‎‏‎‎‎‎‏‎‎‏‏‏‏‎‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ has not accessed your ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‎‎‏‏‎‎‎‏‏‏‏‎‏‏‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‏‎‏‏‏‏‏‎‎‎‏‏‎‏‎‏‎‏‏‏‏‏‎‎View detailed permissions usage‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‏‎‎‏‏‎‎‎‎‎‎‎‎‎‎‎‏‎‎‏‎‏‏‎‏‎‎‏‏‎‏‎‎‎‏‎‎‏‎‏‏‏‎‎‏‏‎‎‎‎‏‏‏‏‎‎Most recent access ‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ ago‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‎‏‎‎‏‎‎‎‏‎‏‏‎‏‏‏‎‏‏‎‎‎‎‎‎‎‏‎‎‎‏‎‏‏‏‏‏‎‎‏‏‏‏‎‏‏‏‎‎‎‏‏‏‏‎‎Allowed‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‏‎‎‏‏‏‎‏‎‎‎‏‎‎‏‏‏‎‏‎‎‎‏‎‎‏‎‎‏‎‎‎‎‏‎‏‎‏‏‎‏‏‎‏‎‎‎‎‎‏‏‎‎‎‏‏‎Denied‎‏‎‎‏‎" ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‎‎‏‎‏‎‏‏‏‎‏‏‏‎‏‏‎‎‏‎‏‏‎‎‎‏‎‎‏‏‏‏‎‎‏‏‎‎‏‏‏‏‎‎‎‏‏‎‎‎‎‎‎‎‏‏‎‎‏‎‎‏‏‎%s‎‏‎‎‏‏‏‎ days‎‏‎‎‏‎ ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‎‎‏‎‏‎‏‏‏‎‏‏‏‎‏‏‎‎‏‎‏‏‎‎‎‏‎‎‏‏‏‏‎‎‏‏‎‎‏‏‏‏‎‎‎‏‏‎‎‎‎‎‎‎‏‏‎1 day‎‏‎‎‏‎ @@ -111,4 +124,31 @@ ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‏‎‏‎‏‎‎‏‎‏‎‎‎‎‏‎‏‎‏‎‎‎‏‎‏‏‎‏‎‎‎‎‏‏‏‏‎‏‎‎‎‏‎‏‏‎‎‎‎‏‎‏‏‏‎‏‎‎‏‎‎‏‏‎%s‎‏‎‎‏‏‏‎ seconds‎‏‎‎‏‎ ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‏‎‏‎‏‎‎‏‎‏‎‎‎‎‏‎‏‎‏‎‎‎‏‎‏‏‎‏‎‎‎‎‏‏‏‏‎‏‎‎‎‏‎‏‏‎‎‎‎‏‎‏‏‏‎‏‎1 second‎‏‎‎‏‎ + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‎‏‏‏‎‎‏‎‎‏‏‏‎‏‎‏‎‏‏‏‎‏‎‏‏‏‏‎‏‎‎‎‏‏‏‎‏‏‏‎‏‎‏‏‎‏‎‎‎‎‏‎‎‎‎‎‎Use <b>‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎</b> as your ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎?‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‏‎‏‏‏‏‎‎‎‏‎‏‎‎‎‎‏‎‏‎‎‎‎‎‎‎‏‎‏‎‎‏‎‏‏‎‎‎‏‎‎‏‎‏‏‎‎‎‎‎‎‎‎‏‎‎Use <b>‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎</b> instead of <b>‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎</b> as your ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎?‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‎‏‏‎‎‏‎‏‎‏‏‏‏‏‎‏‎‏‏‏‎‏‎‏‏‎‏‏‎‏‎‏‏‎‏‎‏‎‎‎‎‏‎‎‎‎‎‎‏‏‏‏‎Permission reminders‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‎‏‎‏‎‏‎‎‏‎‎‏‏‏‏‎‏‏‎‏‏‏‎‎‏‎‎‎‎‎‎‎‏‎‎‎‎‏‎‎‏‎‏‏‏‎‏‏‏‎‏‎‏‏‏‎‎‎‏‎‎‏‏‎%s‎‏‎‎‏‏‏‎ has been using your location‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‏‎‏‏‏‎‎‏‎‏‎‏‏‎‎‏‎‏‏‎‏‎‎‎‏‎‏‎‏‎‎‎‎‎‎‎‎‏‎‎‎‏‏‎‎‎‏‎‎‏‏‏‎‎‎This app can always access your location. Tap to change.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‏‏‏‏‏‎‎‏‏‎‎‏‎‎‏‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‏‏‏‎‏‏‎‏‏‏‏‏‏‎‏‎‎‎‏‎‎‎Default apps‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‏‏‏‎‏‏‏‏‎‎‏‏‏‎‎‎‏‎‏‎‎‏‏‏‎‎‏‎‎‏‎‏‎‎‏‏‎‎‏‏‎‏‏‏‏‏‏‏‏‎‎‎‎No default apps‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‎‏‏‎‏‏‏‏‎‎‎‎‎‎‎‏‏‏‎‏‏‎‏‏‏‎‎‏‎‎‏‎‎‏‏‎‎‏‏‎‏‎‏‏‎‎‏‏‎‎‎‏‏‏‎‏‎Phone app‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‏‏‏‏‎‎‎‎‏‏‏‏‏‎‎‎‏‎‎‏‎‎‏‏‎‏‎‏‏‎‏‏‏‎‏‏‏‏‎‎‏‏‏‎‎‏‎‎SMS app‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‏‏‏‎‏‏‏‎‎‎‏‎‏‏‎‏‎‎‏‎‏‎‎‏‎‏‎‏‏‎‎‎‎‏‎‎‏‎‏‎‎‏‎‎‏‏‏‎‏‎‏‎‎‎‏‎Browser app‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‎‎‏‏‏‎‎‏‎‎‎‏‎‏‎‏‎‎‎‏‎‏‎‎‎‎‎‎‎‎‏‏‏‎‏‏‎‏‏‏‎‎‎‏‎‎‎‎‎‎‏‎‎‏‎Gallery app‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‏‎‎‎‎‏‏‏‏‎‎‎‎‏‏‏‏‏‎‎‎‏‏‎‏‎‏‎‎‎‏‎‏‏‎‏‏‎‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎Music app‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‎‏‎‏‏‎‎‎‏‏‏‏‏‎‏‏‎‎‎‏‏‎‏‏‎‎‎‎‎‏‏‎‏‎‏‏‏‎‏‏‏‏‎‏‏‏‎‏‏‏‏‏‎The app developer says your data may be:‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎‏‏‎‏‏‏‏‏‎‏‎‏‏‏‏‎‎‎‏‏‎‏‎‎‎‎‎‎‎‏‎‏‏‏‏‎‏‎‏‏‏‏‏‏‎‎‏‏‏‎‏‏‎‏‎‎‎If you don’t like how this app developer is using your data you can deny the permission.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‏‎‏‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‏‎‏‏‎‎‏‏‎‎‎‏‎‏‎‏‎‎‎‏‏‎‎‎‎‎‏‎‏‎‏‏‏‏‎‏‏‎‎Uploaded to cloud‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‎‎‏‏‎‏‏‏‎‎‎‏‏‎‏‎‏‎‎‎‎‏‏‎‎‎‏‎‎‎‎‎‎‎‎‏‏‏‎‎‏‎‎‏‎‎‎‎‎‎‎‏‏‎‏‏‎Uploaded to cloud when you explicitly allow it‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‎‏‏‎‎‏‏‏‎‎‎‎‏‎‎‏‏‎‎‏‎‏‎‎‏‏‎‏‏‏‎‏‏‎‎‏‏‏‏‎‏‎‏‏‏‎‎‎‎‎‏‏‏‏‎Shared with advertisers or businesses‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‏‎‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‎‎‏‎‏‎‎‏‏‎‎‏‎‏‏‎‏‏‎‎‏‎‎‎‎‎‎‏‎‏‎‏‏‏‏‎‎Shared with advertisers or businesses when you explicitly allow it‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‎‎‎‎‎‎‎‏‏‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎‏‎‏‎‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‎‏‏‏‏‎‎‏‏‏‎Used for monetization‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‏‎‎‎‎‏‏‎‏‎‎‎‏‏‎‎‏‏‎‎‎‏‎‏‎‎‎‏‏‏‎‏‎‏‎‎‏‏‏‏‎‏‏‏‏‎‏‏‎‎‎‎‎‎Used for monetization when you explicitly allow it‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‎‏‏‎‏‎‏‏‏‎‏‎‎‎‏‎‎‏‎‎‎‏‏‎‎‎‏‏‎‏‎‏‏‎‏‎‏‎‏‎‎‏‎‎‏‎‏‎‏‎‏‏‎‏‏‏‎Saved and analyzed forever‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‎‎‎‎‏‏‎‎‎‏‎‏‏‏‎‎‏‎‏‏‏‏‏‎‏‎‏‏‏‏‎‎‏‎‏‏‎‎‎‏‏‎‎‎‎‎‎‎‏‎‏‏‏‏‎Saved and analyzed for a duration you specify‎‏‎‎‏‎" + + ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‎‏‎‏‏‎‏‎‏‏‏‏‏‏‏‎‎‎‏‎‎‎‏‎‏‏‏‎‎‏‏‎‎‏‏‎‏‏‎‏‎‎‏‏‏‏‎‎‏‎‎‏‏‏‏‎‎Saved and analyzed for ‎‏‎‎‏‏‎%s‎‏‎‎‏‏‏‎ weeks‎‏‎‎‏‎ + ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‎‏‎‏‏‎‏‎‏‏‏‏‏‏‏‎‎‎‏‎‎‎‏‎‏‏‏‎‎‏‏‎‎‏‏‎‏‏‎‏‎‎‏‏‏‏‎‎‏‎‎‏‏‏‏‎‎Saved and analyzed for 1 week‎‏‎‎‏‎ + + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‎‎‎‎‏‎‏‏‎‎‏‎‎‎‎‎‏‏‏‏‎‏‎‎‎‎‏‎‏‏‎‎‏‏‏‎‎‏‏‏‎‏‎‎‏‎‎‏‎‏‎‎‏‏‎The app developer did not specify how the app uses your data.‎‏‎‎‏‎" diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml index ae2283756..d05ff8c02 100644 --- a/res/values-es-rUS/strings.xml +++ b/res/values-es-rUS/strings.xml @@ -61,6 +61,7 @@ "El administrador inhabilitó el acceso en segundo plano" "El administrador habilitó el acceso en segundo plano" "El administrador habilitó el acceso en primer plano" + "Permiso establecido por el sistema" @@ -95,6 +96,22 @@ "Ningún uso de permisos" "Uso de permisos de la app" "Hace %1$s" + "Permitir" + "Permitir todo el tiempo" + "Permitir solo cuando la app está en uso" + "Rechazar" + "Permiso de %1$s" + "Acceso de %1$s a %2$s" + "%1$s accedió a tu %2$s hace %3$s." + + + "Ver uso de permisos detallado" + + + + + + %s días 1 día @@ -111,4 +128,44 @@ %s segundos 1 segundo + "¿Quieres usar <b>%1$s</b> como %2$s?" + "¿Quieres usar <b>%1$s</b> en lugar de <b>%1$s</b> como %2$s?" + + + + + + + + + + + "App de teléfono" + "app de SMS" + "App de navegador" + "App de Galería" + "App de Música" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index 05650af2d..b7dc04c74 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -61,6 +61,7 @@ "El administrador ha inhabilitado el acceso en segundo plano" "El administrador ha habilitado el acceso en segundo plano" "El administrador ha habilitado el acceso en primer plano" + "Permiso establecido por el sistema" @@ -95,6 +96,22 @@ "No se han usado los permisos" "Uso permisos de la aplicación" "Hace %1$s" + "Permitir" + "Permitir siempre" + "Permitir solo mientras las aplicaciones están en uso" + "Denegar" + "Permiso de %1$s" + "Acceso de %2$s a tu %1$s" + "%1$s ha accedido a tu %2$s hace %3$s." + + + "Ver el uso de permisos detallado" + + + + + + %s días 1 día @@ -111,4 +128,44 @@ %s segundos 1 segundo + "¿Quieres usar <b>%1$s</b> como tu %2$s?" + "¿Quieres usar <b>%1$s</b> en lugar de <b>%1$s</b> como tu %2$s?" + + + + + + + + + + + "Aplicación de teléfono" + "Aplicación de SMS" + "Aplicación de navegador" + "Aplicación de galería" + "Aplicación de música" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml index 8371f73cf..a9703c305 100644 --- a/res/values-et/strings.xml +++ b/res/values-et/strings.xml @@ -61,6 +61,7 @@ "Administraator keelas juurdepääsu taustale" "Administraator lubas juurdepääsu taustale" "Administraator lubas juurdepääsu esiplaanile" + "Süsteemi määratud luba" @@ -95,6 +96,22 @@ "Lube pole kasutatud" "Rakenduse lubade kasutus" "%1$s tagasi" + "Luba" + "Luba alati" + "Luba ainult rakenduse kasutamise ajal" + "Keela" + "Luba %1$s" + "Rakenduse %2$s juurdepääs loale %1$s" + "Rakendus %1$s pääses loale %2$s juurde %3$s tagasi." + + + "Kuva lubade kasutamise üksikasjad" + + + + + + %s päeva 1 päev @@ -111,4 +128,44 @@ %s sekundit 1 sekund + "Kas kasutada rakendust <b>%1$s</b> järgmisena: %2$s?" + "Kas kasutada rakendust <b>%1$s</b> rakenduse <b>%1$s</b> asemel järgmisena: %2$s?" + + + + + + + + + + + "Telefonirakendus" + "SMS-i rakendus" + "Brauserirakendus" + "Galeriirakendus" + "Muusikarakendus" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml index f837f177a..3fca8e3c7 100644 --- a/res/values-eu/strings.xml +++ b/res/values-eu/strings.xml @@ -61,6 +61,7 @@ "Administratzaileak atz. planoa atzitzeko aukera desgaitu du" "Administratzaileak atzeko planoa atzitzeko aukera gaitu du" "Administratzaileak aurreko planoa atzitzeko aukera gaitu du" + "Sistemak ezarri du baimena" @@ -95,6 +96,18 @@ "Ez da eskatu baimenik" "Aplikazio-baimenen erabilera" "Duela %1$s" + "Baimendu" + "Baimendu beti" + "Baimendu aplikazioa erabiltzen ari zarenean soilik" + "Ukatu" + "%1$s atzitzeko baimena" + "%1$s atzitzeko %2$s aplikazioaren baimena" + "%1$s aplikazioak %2$s atzitu du duela %3$s." + "%1$s aplikazioak ez du atzitu %2$s." + "Ikusi baimenen erabilera xehatua" + "Azken sarbidea: duela %1$s" + "Baimenduta" + "Ukatuta" %s egun 1 egun @@ -111,4 +124,34 @@ %s segundo 1 segundo + "<b>%1$s</b> erabili nahi duzu %2$s gisa?" + "<b>%1$s</b> erabili nahi duzu (eta ez <b>%1$s</b>) %2$s gisa?" + + + + + + + "Aplikazio lehenetsiak" + "Ez dago aplikazio lehenetsirik" + "Telefonoa" + "SMS" + "Arakatzailea" + "Galeria aplikazioa" + "Musika aplikazioa" + "Aplikazioaren garatzaileak datuekin hau gertatuko dela dio:" + "Ez bazaizu gustatzen aplikazioaren garatzaileak zure datuak nola erabiltzen dituen, baimena ukatzeko aukera duzu." + "Hodeira kargatuko dira" + "Hodeira kargatuko dira, horretarako baimena berariaz ematen baduzu" + "Iragarleekin edo enpresekin partekatuko dira" + "Iragarleekin edo enpresekin partekatuko dira, horretarako baimena berariaz ematen baduzu" + "Dirua irabazteko erabiliko dira" + "Dirua irabazteko erabiliko dira, horretarako baimena berariaz ematen baduzu" + "Betiko gordeko eta analizatuko dira" + "Gorde eta analizatu egingo dira zuk zehazten duzun epean" + + %s astez gorde eta analizatuko dira + Astebetez gorde eta analizatuko dira + + "Aplikazioaren garatzaileak ez du zehaztu aplikazioak nola erabiltzen dituen datuak." diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml index dce46d937..f2613fe5e 100644 --- a/res/values-fa/strings.xml +++ b/res/values-fa/strings.xml @@ -61,6 +61,7 @@ "دسترسی به پس‌زمینه توسط سرپرست غیرفعال شد" "دسترسی به پس‌زمینه توسط سرپرست فعال شد" "دسترسی به پیش‌زمینه توسط سرپرست فعال شد" + "مجوز تنظیم‌شده توسط سیستم" @@ -95,6 +96,22 @@ "هیچ مجوزی استفاده نشده است" "استفاده از مجوزهای برنامه" "%1$s قبل" + "مجاز" + "همیشه مجاز بودن" + "مجاز بودن تنها هنگام استفاده از برنامه" + "اجازه ندادن" + "مجوز %1$s" + "دسترسی %1$s برای %2$s" + "%1$s %3$s پیش به %2$s دسترسی یافت." + + + "مشاهده استفاده از مجوزها با جزئیات" + + + + + + %s روز %s روز @@ -111,4 +128,44 @@ %s ثانیه %s ثانیه + "‏از <b>%1$s</b> به‌عنوان %2$s شما استفاده شود؟" + "‏از <b>%1$s</b> به‌جای <b>%1$s</b> به‌عنوان %2$s شما استفاده شود؟" + + + + + + + + + + + "برنامه تلفن" + "برنامه پیامک" + "برنامه مرورگر" + "برنامه گالری" + "برنامه موسیقی" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml index 2a9eebcad..696a0cce4 100644 --- a/res/values-fi/strings.xml +++ b/res/values-fi/strings.xml @@ -61,6 +61,7 @@ "Järjestelmänvalvoja estää taustakäytön" "Järjestelmänvalvoja sallii taustakäytön" "Järjestelmänvalvoja sallii käytön etualalla" + "Käyttöoikeudet määritetty järjestelmän mukaan" @@ -95,6 +96,22 @@ "Käyttöoikeuksia ei käytetty" "Sovelluksen käyttöoikeudet" "%1$s sitten" + "Salli" + "Salli aina" + "Salli vain, kun sovellusta käytetään" + "Estä" + "Käyttöoikeus: %1$s" + "%2$s pyytää käyttöoikeutta: %1$s" + "%2$s oli sovelluksen (%1$s) käytössä %3$s sitten" + + + "Näytä tarkat käyttöoikeustiedot" + + + + + + %s päivää 1 päivä @@ -111,4 +128,44 @@ %s sekuntia 1 sekunti + "Haluatko, että <b>%1$s</b> on jatkossa %2$s?" + "Haluatko, että <b>%1$s</b> (tällä hetkellä <b>%1$s</b>) on jatkossa %2$s?" + + + + + + + + + + + "Puhelin-sovellus" + "Tekstiviestisovellus" + "Selainsovellus" + "Galleriasovellus" + "Musiikkisovellus" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml index 65ddcd25e..049caf706 100644 --- a/res/values-fr-rCA/strings.xml +++ b/res/values-fr-rCA/strings.xml @@ -61,6 +61,7 @@ "L\'accès en arrière-plan est désactivé par l\'administrateur" "L\'accès en arrière-plan est activé par l\'administrateur" "L\'accès en avant-plan est activé par l\'administrateur" + "Autorisation définie par le système" @@ -95,6 +96,22 @@ "Aucune autoris. d\'utilisation" "Util. des autoris. de l\'appli" "Il y a %1$s" + "Autoriser" + "Autoriser tout le temps" + "Autoriser uniquement lorsque l\'appli est en cours d\'utilis." + "Refuser" + "Autorisation %1$s" + "Accès à %1$s pour %2$s" + "%1$s a accédé à votre %2$s il y a %3$s." + + + "Afficher les autorisations d\'utilisation détaillées" + + + + + + %s jour %s jours @@ -111,4 +128,44 @@ %s seconde %s secondes + "Utiliser <b>%1$s</b> comme %2$s?" + "Utiliser <b>%1$s</b> au lieu de <b>%1$s</b> comme %2$s?" + + + + + + + + + + + "Application Téléphone" + "Application de messagerie texte" + "Application de navigateur" + "Application de galerie" + "Application de musique" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index 73a4cb01a..af807d4c4 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -61,6 +61,7 @@ "Accès en arrière-plan désactivé par l\'administrateur" "Accès en arrière-plan activé par l\'administrateur" "Accès au premier plan activé par l\'administrateur" + "Autorisation définie par le système" @@ -95,6 +96,22 @@ "Aucune autorisation utilisée" "Utilisation des autorisations" "Il y a %1$s" + "Autoriser" + "Toujours autoriser" + "Autoriser seulement quand l\'appli est en cours d\'utilisation" + "Refuser" + "Autorisation : %1$s" + "L\'application %2$s est autorisée à accéder à votre/vos %1$s" + "%1$s a accédé à votre/vos %2$s il y a %3$s." + + + "Afficher l\'utilisation détaillée des autorisations" + + + + + + %s jour %s jours @@ -111,4 +128,44 @@ %s seconde %s secondes + "Utiliser <b>%1$s</b> comme %2$s ?" + "Utiliser <b>%1$s</b> au lieu de <b>%1$s</b> comme %2$s ?" + + + + + + + + + + + "Application Téléphone" + "Application de SMS" + "Application de navigateur" + "Application Galerie" + "Application Musique" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml index 193544376..477101e02 100644 --- a/res/values-gl/strings.xml +++ b/res/values-gl/strings.xml @@ -61,6 +61,7 @@ "O administrador desactivou o acceso en segundo plano" "O administrador activou o acceso en segundo plano" "O administrador activou o acceso en primeiro plano" + "Permiso establecido polo sistema" @@ -95,6 +96,22 @@ "Non se utilizaron os permisos" "Uso dos permisos da aplicación" "Hai %1$s" + "Permitir" + "Permitir sempre" + "Permitir só cando se estea utilizando a aplicación" + "Non permitir" + "Permiso de %1$s" + "Permiso de %1$s para %2$s" + "%1$s accedeu hai %3$s ao seguinte: %2$s." + + + "Consulta os detalles sobre o uso dos permisos" + + + + + + %s días 1 día @@ -111,4 +128,44 @@ %s segundos 1 segundo + "Queres utilizar a aplicación <b>%1$s</b> como %2$s?" + "Queres utilizar a aplicación <b>%1$s</b> en lugar de usar <b>%1$s</b> como %2$s?" + + + + + + + + + + + "Aplicación de teléfono" + "Aplicación de SMS" + "Aplicación de navegador" + "Aplicación Galería" + "Aplicación Música" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml index bcf37370d..6d5bc2423 100644 --- a/res/values-gu/strings.xml +++ b/res/values-gu/strings.xml @@ -61,6 +61,7 @@ "વ્યવસ્થાપકે બૅકગ્રાઉન્ડ ઍક્સેસ બંધ કર્યો છે" "વ્યવસ્થાપકે બૅકગ્રાઉન્ડ ઍક્સેસ ચાલુ કર્યો છે" "વ્યવસ્થાપકે ફૉરગ્રાઉન્ડ ઍક્સેસ ચાલુ કર્યો છે" + "સિસ્ટમ દ્વારા પરવાનગી સેટ કરવામાં આવી છે" @@ -95,6 +96,22 @@ "પરવાનગીનો ઉપયોગ થયો નથી" "અ‍ૅપ પરવાનગીઓનો ઉપયોગ" "%1$s પહેલાં" + "મંજૂરી આપો" + "હંમેશાં મંજૂરી આપો" + "માત્ર અ‍ૅપ ઉપયોગમાં હોય ત્યારે જ મંજૂરી આપો" + "નકારો" + "%1$s પરવાનગી" + "%2$s માટે %1$s ઍક્સેસ" + "%1$s દ્વારા તમારી %2$sને %3$s પહેલાં અ‍ૅક્સેસ કરવામાં આવી હતી." + + + "પરવાનગીઓનો વિગતવાર ઉપયોગ જુઓ" + + + + + + %s દિવસ %s દિવસ @@ -111,4 +128,44 @@ %s સેકંડ %s સેકંડ + "<b>%1$s</b>નો તમારા %2$s તરીકે ઉપયોગ કરીએ?" + "<b>%1$s</b>ને બદલે <b>%1$s</b>નો તમારા %2$s તરીકે ઉપયોગ કરીએ?" + + + + + + + + + + + "ફોન ઍપ" + "SMS ઍપ" + "બ્રાઉઝર ઍપ" + "ગૅલેરી ઍપ" + "મ્યુઝિક ઍપ" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml index 3d1846aa1..a3269edf9 100644 --- a/res/values-hi/strings.xml +++ b/res/values-hi/strings.xml @@ -61,6 +61,7 @@ "एडमिन ने बैकग्राउंड में चलने का एक्सेस बंद कर दिया है" "एडमिन ने बैकग्राउंड में चलने का एक्सेस चालू कर दिया है" "एडमिन ने स्क्रीन पर दिखाने का एक्सेस चालू कर दिया है" + "अनुमति सिस्टम ने सेट की है" @@ -95,6 +96,22 @@ "अनुमति का इस्तेमाल नहीं हुआ" "ऐप्लिकेशन अनुमतियों इस्तेमाल" "%1$s पहले" + "मंज़ूरी दें" + "हमेशा मंज़ूरी दें" + "तभी मंज़ूरी दें जब ऐप्लिकेशन का इस्तेमाल हो रहा हो" + "नामंज़ूर करें" + "%1$s अनुमति" + "%2$s के लिए %1$s" + "%1$s ने %3$s पहले आपकी %2$s का इस्तेमाल किया है." + + + "अनुमतियों के इस्तेमाल से जुड़ी ज़्यादा जानकारी देखें" + + + + + + %s दिन %s दिन @@ -111,4 +128,44 @@ %s सेकंड %s सेकंड + "क्या आप <b>%1$s</b> का इस्तेमाल अपने %2$s के रूप में करना चाहते हैं?" + "क्या आप <b&gt%1$s</b&gt के बजाय <b>%1$s</b> का इस्तेमाल अपने %2$s के रूप में करना चाहते हैं?" + + + + + + + + + + + "फ़ोन ऐप्लिकेशन" + "मैसेज (एसएमएस) ऐप्लिकेशन" + "ब्राउज़र ऐप्लिकेशन" + "गैलरी ऐप्लिकेशन" + "संगीत ऐप्लिकेशन" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml index bb5a9b960..d07ef72fd 100644 --- a/res/values-hr/strings.xml +++ b/res/values-hr/strings.xml @@ -62,6 +62,7 @@ "Pristup iz pozadine onemogućio je administrator" "Pristup iz pozadine omogućio je administrator" "Pristup iz prednjeg plana omogućio je administrator" + "Dopuštenje koje je postavio sustav" @@ -96,6 +97,22 @@ "Nema upotreba dopuštenja" "Upotreba dopuštenja aplikacije" "prije %1$s" + "Dopusti" + "Dopusti cijelo vrijeme" + "Dopusti samo dok je aplikacija u upotrebi" + "Odbij" + "Dopuštenje %1$s" + "Pristup dopuštenju %1$s za aplikaciju %2$s" + "Aplikacija %1$s pristupila je dopuštenju %2$s prije %3$s." + + + "Pregledajte detaljnu upotrebu dopuštenja" + + + + + + %s dana %s dana @@ -116,4 +133,44 @@ %s sekunde %s sekundi + "Upotrijebiti naziv aplikacije <b>%1$s</b> kao %2$s?" + "Upotrijebiti novi naziv aplikacije <b>%1$s</b> umjesto trenutačnog <b>%1$s</b> kao %2$s?" + + + + + + + + + + + "Aplikacija Telefon" + "Aplikacija za SMS" + "Aplikacija preglednika" + "Aplikacija Galerija" + "Aplikacija Glazba" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml index 93efd92b5..943a72bd2 100644 --- a/res/values-hu/strings.xml +++ b/res/values-hu/strings.xml @@ -61,6 +61,7 @@ "A rendszergazda letiltotta a háttérhozzáférést" "A rendszergazda engedélyezte a háttérhozzáférést" "A rendszergazda engedélyezte az előtérbeli hozzáférést" + "A rendszer által beállított engedély" @@ -95,6 +96,22 @@ "Nincs engedélyhasználat" "Alkalmazásengedély-használat" "Ennyi idővel ezelőtt: %1$s" + "Engedélyezés" + "Mindig engedélyezett" + "Csak akkor engedélyezett, ha az alkalmazás használatban van" + "Tiltás" + "%1$s engedély" + "%1$s hozzáférés %2$s számára" + "A(z) %1$s alkalmazás hozzáfért a következőhöz: %2$s (ennyi ideje: %3$s)." + + + "Engedélyhasználat részletes adatainak megtekintése" + + + + + + %s nap 1 nap @@ -111,4 +128,44 @@ %s másodperc 1 másodperc + "A(z) <b>%1$s</b> alkalmazást szeretné használni a következőként: %2$s?" + "A(z) <b>%1$s</b> alkalmazást szeretné használni a(z) <b>%1$s</b> helyett a következőként: %2$s?" + + + + + + + + + + + "Telefon alkalmazás" + "SMS-küldő" + "Böngésző" + "Galériaalkalmazás" + "Zenealkalmazás" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml index c27926ee0..6f9b14e5f 100644 --- a/res/values-hy/strings.xml +++ b/res/values-hy/strings.xml @@ -61,6 +61,7 @@ "Ադմինիստրատորն անջատել է հասանելիությունը ֆոնային ռեժիմում" "Ադմինիստրատորը միացրել է հասանելիությունը ֆոնային ռեժիմում" "Ադմինիստրատորը միացրել է հասանելիությունն ակտիվ ռեժիմում" + "Թույլտվությունը տրվել է համակարգի կողմից" @@ -95,6 +96,22 @@ "Թույլտվություններ չեն կիրառվել" "Թույլտվությունների օգտագործում" "%1$s առաջ" + "Թույլատրել" + "Թույլատրել միշտ" + "Թույլատրել, միայն երբ հավելվածն օգտագործվում է" + "Մերժել" + %1$s» թույլտվություն" + %1$s» թույլտվության տրամադրում %2$s հավելվածին" + "%1$s հավելվածը ստացել է «%2$s» թույլտվությունը %3$s առաջ:" + + + "Դիտել թույլտվությունների օգտագործման մանրամասները" + + + + + + %s օր %s օր @@ -111,4 +128,44 @@ %s վայրկյան %s վայրկյան + "Օգտագործե՞լ <b>%1$s</b> հավելվածը որպես ձեր %2$s:" + "Օգտագործե՞լ <b>%1$s</b> հավելվածը <b>%1$s</b> հավելվածի փոխարեն որպես ձեր %2$s:" + + + + + + + + + + + "«Հեռախոս» հավելված" + "«SMS» հավելված" + "«Դիտարկիչ» հավելված" + "Ցուցասրահ" + "Երաժշտություն" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml index fc89a69b3..e81856911 100644 --- a/res/values-in/strings.xml +++ b/res/values-in/strings.xml @@ -61,6 +61,7 @@ "Akses latar belakang dinonaktifkan oleh admin" "Akses latar belakang diaktifkan oleh admin" "Akses latar depan diaktifkan oleh admin" + "Izin disetel oleh sistem" @@ -95,6 +96,22 @@ "Tidak ada penggunaan izin" "Penggunaan izin aplikasi" "%1$s yang lalu" + "Izinkan" + "Izinkan sepanjang waktu" + "Izinkan hanya saat aplikasi sedang digunakan" + "Tolak" + "Izin %1$s" + "Akses %1$s untuk %2$s" + "%1$s mengakses %2$s Anda %3$s yang lalu." + + + "Melihat penggunaan izin mendetail" + + + + + + %s hari 1 hari @@ -111,4 +128,44 @@ %s detik 1 detik + "Gunakan <b>%1$s</b> sebagai %2$s Anda?" + "Gunakan <b>%1$s</b> dan bukan <b>%1$s</b> sebagai %2$s Anda?" + + + + + + + + + + + "Aplikasi telepon" + "Aplikasi SMS" + "Aplikasi browser" + "Aplikasi Galeri" + "Aplikasi Musik" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml index 2589e9736..ca7f87b37 100644 --- a/res/values-is/strings.xml +++ b/res/values-is/strings.xml @@ -61,6 +61,7 @@ "Bakgrunnsaðgangur gerður óvirkur af kerfisstjóra" "Bakgrunnsaðgangur gerður virkur af kerfisstjóra" "Forgrunnsaðgangur gerður virkur af kerfisstjóra" + "Heimildir sem kerfið hefur stillt" @@ -95,6 +96,22 @@ "Engin heimildanotkun" "Notkun heimilda forrits" "fyrir %1$s" + "Leyfa" + "Leyfa alltaf" + "Leyfa aðeins þegar forritið er í notkun" + "Hafna" + "%1$s heimild" + "%1$s aðgangur að %2$s" + "%1$s fékk aðgang að %2$s þínu fyrir %3$s." + + + "Skoða nákvæma heimildanotkun" + + + + + + %s dagur %s dagar @@ -111,4 +128,44 @@ %s sekúnda %s sekúndur + "Nota <b>%1$s</b> sem %2$s?" + "Nota <b>%1$s</b> í stað <b>%1$s</b&gt sem %2$s?" + + + + + + + + + + + "Símaforrit" + "SMS-forrit" + "Vafraforrit" + "Myndasafnsforrit" + "Tónlistarforrit" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml index 7e8134fd8..31e6a21e1 100644 --- a/res/values-it/strings.xml +++ b/res/values-it/strings.xml @@ -61,6 +61,7 @@ "Accesso in background disattivato dall\'amministratore" "Accesso in background attivato dall\'amministratore" "Accesso in primo piano attivato dall\'amministratore" + "Autorizzazione impostata dal sistema" @@ -95,6 +96,22 @@ "Autorizzazioni non usate" "Uso delle autorizzazioni app" "%1$s fa" + "Consenti" + "Consenti sempre" + "Consenti solo mentre l\'app è in uso" + "Nega" + "Autorizzazione per i dati di %1$s" + "Accesso ai dati di %1$s per l\'app %2$s" + "L\'app %1$s ha avuto accesso ai tuoi dati di %2$s %3$s fa." + + + "Consulta l\'uso dettagliato delle autorizzazioni" + + + + + + %s giorni 1 giorno @@ -111,4 +128,44 @@ %s secondi 1 secondo + "Utilizzare <b>%1$s</b> come %2$s?" + "Utilizzare <b>%1$s</b> anziché <b>%1$s</b> come %2$s?" + + + + + + + + + + + "App Telefono" + "App per SMS" + "App browser" + "App Galleria" + "App per la musica" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml index 5ff40136c..9d2de55b5 100644 --- a/res/values-iw/strings.xml +++ b/res/values-iw/strings.xml @@ -63,6 +63,7 @@ "הגישה ברקע מושבתת על ידי מנהל מערכת" "הגישה ברקע מופעלת על ידי מנהל מערכת" "הגישה במצב פעיל מופעלת על ידי מנהל מערכת" + "ההרשאה הוגדרה על ידי המערכת" @@ -97,6 +98,22 @@ "אין שימוש בהרשאות" "שימוש בהרשאות האפליקציה" "לפני %1$s" + "לאישור" + "לאישור כל הזמן" + "לאישור רק בזמן שהאפליקציה בשימוש" + "אני לא מרשה" + "הרשאה ל%1$s" + "גישה ל%1$s עבור %2$s" + "נעשתה גישה ל%2$s על ידי %1$s לפני %3$s." + + + "הצגת שימוש מפורט בהרשאות" + + + + + + יומיים (%s) %s ימים @@ -121,4 +138,44 @@ %s שניות שנייה אחת + "‏האם להשתמש באפליקציה <b>%1$s</b> בתור %2$s?" + "‏האם להשתמש באפליקציה <b>%1$s</b> בתור %2$s במקום %1$s?" + + + + + + + + + + + "אפליקציית \'טלפון\'" + "‏אפליקציית SMS" + "אפליקציית דפדפן" + "גלריית האפליקציות" + "אפליקציית מוזיקה" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml index 7f15211e6..a043d4b6a 100644 --- a/res/values-ja/strings.xml +++ b/res/values-ja/strings.xml @@ -61,6 +61,7 @@ "バックグラウンドでのアクセスは管理者が無効に設定しています" "バックグラウンドでのアクセスは管理者が有効に設定しています" "フォアグラウンドでのアクセスは管理者が有効に設定しています" + "システムによって設定された権限" @@ -95,6 +96,22 @@ "権限の使用はなし" "アプリの権限の使用" "%1$s 前" + "許可" + "常に許可" + "アプリが使用中の場合のみ許可" + "許可しない" + "%1$sの権限" + "%2$s%1$sへのアクセス権" + "%1$s%3$s前に%2$sにアクセスしました。" + + + "権限の使用に関する詳細を表示" + + + + + + %s 1日 @@ -111,4 +128,44 @@ %s 1秒 + "<b>%1$s</b> を %2$sとして使用しますか?" + "%1$s の代わりに、<b>%1$s</b> を %2$sとして使用しますか?" + + + + + + + + + + + "電話アプリ" + "SMS アプリ" + "ブラウザアプリ" + "ギャラリー アプリ" + "音楽アプリ" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml index 86a90cdbc..830940eb6 100644 --- a/res/values-ka/strings.xml +++ b/res/values-ka/strings.xml @@ -61,6 +61,7 @@ "ფონზე წვდომა გათიშულია ადმინისტრატორის მიერ" "ფონზე წვდომა დაშვებულია ადმინისტრატორის მიერ" "წინა პლანზე წვდომა დაშვებულია ადმინისტრატორის მიერ" + "სისტემის მიერ დაყენებული ნებართვა" @@ -95,6 +96,22 @@ "ამ ნებართვებს აპები არ იყენებს" "აპის ნებართვებით სარგებლობა" "%1$sს წინ" + "დაშვება" + "ყოველთვის დაშვება" + "მხოლოდ აპის გამოყენებისას დაშვება" + "უარყოფა" + "ნებართვა: %1$s" + "%1$s: წვდომა %2$s-ისთვის" + "%1$s-მა გამოიყენა თქვენი %2$s %3$sს წინ." + + + "ნებართვების გამოყენების დეტალურად ნახვა" + + + + + + %s დღე 1 დღე @@ -111,4 +128,44 @@ %s წამი 1 წამი + "გსურთ, გამოიყენოთ <b>%1$s</b>, როგორც %2$s?" + "გსურთ, გამოიყენოთ <b>%1$s</b> (<b>%1$s</b>-ის ნაცვლად), როგორც %2$s?" + + + + + + + + + + + "ტელეფონის აპი" + "SMS აპი" + "ბრაუზერის აპი" + "გალერეის აპი" + "მუსიკის აპი" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml index 7aff68fdd..9fcb69e39 100644 --- a/res/values-kk/strings.xml +++ b/res/values-kk/strings.xml @@ -61,6 +61,7 @@ "Әкімші фондық режимде кіруге тыйым салған" "Әкімші фондық режимде кіруге рұқсат еткен" "Әкімші экрандық режимде кіруге рұқсат еткен" + "Жүйе орнатқан рұқсат" @@ -95,6 +96,22 @@ "Рұқсаттар пайдаланылмаған" "Қолданба рұқсаттарын пайдалану" "%1$s бұрын" + "Рұқсат беру" + "Әрдайым рұқсат беру" + "Қолданба пайдаланылып жатқанда ғана рұқсат беру" + "Келіспеу" + "%1$s рұқсаты" + "%2$s қолданбасына арналған %1$s рұқсатына кіру" + "%1$s қолданбасы %2$s рұқсатына %3$s бұрын кірді." + + + "Рұқсаттардың пайдаланылуы туралы мәліметтерді көру" + + + + + + %s күн 1 күн @@ -111,4 +128,44 @@ %s секунд 1 секунд + "<b>%1$s</b> қолданбасы %2$s рөлінде пайдаланылсын ба?" + "<b>%1$s</b> қолданбасы <b>%1$s</b> қолданбасының орнына %2$s ретінде пайдаланылсын ба?" + + + + + + + + + + + "Телефон қолданбасы" + "SMS қолданбасы" + "Браузер қолданбасы" + "Галерея қолданбасы" + "Музыка қолданбасы" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml index f41ec8a09..7963e5471 100644 --- a/res/values-km/strings.xml +++ b/res/values-km/strings.xml @@ -61,6 +61,7 @@ "ការចូល​ប្រើ​ផ្ទៃខាងក្រោយ​ត្រូវបានបិទដោយ​អ្នកគ្រប់គ្រង" "ការចូល​ប្រើ​ផ្ទៃខាងក្រោយ​ត្រូវបានបើកដោយ​អ្នកគ្រប់គ្រង" "ការចូល​ប្រើ​ផ្ទៃខាងមុខ​ត្រូវបានបើកដោយ​អ្នកគ្រប់គ្រង" + "ការអនុញ្ញាត​ដែលបានកំណត់​ដោយប្រព័ន្ធ" @@ -95,6 +96,22 @@ "គ្មាន​ការប្រើប្រាស់​ការអនុញ្ញាត​ទេ" "ការប្រើប្រាស់​ការអនុញ្ញាត​កម្មវិធី" "%1$s មុន" + "អនុញ្ញាត" + "អនុញ្ញាតគ្រប់ពេល" + "អនុញ្ញាត​ពេល​កំពុង​ប្រើប្រាស់​កម្មវិធីតែ​ប៉ុណ្ណោះ" + "បដិសេធ" + "ការអនុញ្ញាត %1$s" + "ការចូលប្រើ %1$s សម្រាប់ %2$s" + "%1$s បាន​ចូលប្រើ %2$s របស់អ្នកកាលពី %3$s មុន។" + + + "មើល​ការ​ប្រើប្រាស់​ការអនុញ្ញាត​លម្អិត" + + + + + + %s ថ្ងៃ 1 ថ្ងៃ @@ -111,4 +128,44 @@ %s វិនាទី 1 វិនាទី + "ប្រើ <b>%1$s</b> ជា​ %2$s របស់អ្នក?" + "ប្រើ <b>%1$s</b> ជំនួសឱ្យ​ <b>%1$s</b>​ ជា %2$s របស់អ្នក?" + + + + + + + + + + + "កម្មវិធីទូរសព្ទ" + "កម្មវិធីផ្ញើសារ SMS" + "កម្មវិធីរុករកតាមអ៊ីនធឺណិត" + "កម្មវិធីសាល​រូបភាព" + "កម្មវិធី​តន្រី្ត" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml index 5e35d87d1..c0bc099bd 100644 --- a/res/values-kn/strings.xml +++ b/res/values-kn/strings.xml @@ -61,6 +61,7 @@ "ಹಿನ್ನೆಲೆ ಪ್ರವೇಶವನ್ನು ನಿರ್ವಾಹಕರು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿದ್ದಾರೆ" "ಹಿನ್ನೆಲೆ ಪ್ರವೇಶವನ್ನು ನಿರ್ವಾಹಕರು ಸಕ್ರಿಯಗೊಳಿಸಿದ್ದಾರೆ" "ಮುನ್ನೆಲೆ ಪ್ರವೇಶವನ್ನು ನಿರ್ವಾಹಕರು ಸಕ್ರಿಯಗೊಳಿಸಿದ್ದಾರೆ" + "ಸಿಸ್ಟಂ ಅನುಮತಿಯನ್ನು ಹೊಂದಿಸಿದೆ" @@ -95,6 +96,22 @@ "ಅನುಮತಿಯ ಬಳಕೆಗಳು ಇಲ್ಲ" "ಆ್ಯಪ್‌ ಅನುಮತಿಗಳ ಬಳಕೆ" "%1$s ನಿಮಿಷಗಳ ಹಿಂದೆ" + "ಅನುಮತಿಸಿ" + "ಎಲ್ಲಾ ಸಮಯದಲ್ಲೂ ಅನುಮತಿಸಿ" + "ಆ್ಯಪ್ ಬಳಕೆಯಲ್ಲಿದ್ದಾಗ ಮಾತ್ರ ಅನುಮತಿಸಿ" + "ನಿರಾಕರಿಸಿ" + "%1$s ಅನುಮತಿ" + "%2$s ಆ್ಯಪ್‌ಗಾಗಿ %1$s ಪ್ರವೇಶ" + "%1$s ಆ್ಯಪ್ ನಿಮ್ಮ %2$s ಅನ್ನು %3$s ಹಿಂದೆ ಪ್ರವೇಶಿಸಿದೆ." + + + "ವಿವರವಾದ ಅನುಮತಿಗಳ ಬಳಕೆಯನ್ನು ವೀಕ್ಷಿಸಿ" + + + + + + %s ದಿನಗಳು %s ದಿನಗಳು @@ -111,4 +128,44 @@ %s ಸೆಕೆಂಡುಗಳು %s ಸೆಕೆಂಡುಗಳು + "<b>%1$s</b> ಅನ್ನು ನಿಮ್ಮ %2$s ಎಂದು ಬಳಸುವುದೇ?" + "<b>%1$s</b> ಅನ್ನು <b>%1$s</b> ರ ಬದಲಿಗೆ ನಿಮ್ಮ %2$s ಎಂದು ಬಳಸುವುದೇ?" + + + + + + + + + + + "ಫೋನ್ ಆ್ಯಪ್" + "ಎಸ್ಎಂಎಸ್ ಆ್ಯಪ್" + "ಬ್ರೌಸರ್ ಆ್ಯಪ್" + "ಗ್ಯಾಲರಿ ಆ್ಯಪ್‌" + "ಸಂಗೀತ ಆ್ಯಪ್‌" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml index c3f0b8a71..3720f2d17 100644 --- a/res/values-ko/strings.xml +++ b/res/values-ko/strings.xml @@ -61,6 +61,7 @@ "관리자가 백그라운드 액세스를 사용 중지함" "관리자가 백그라운드 액세스를 사용 설정함" "관리자가 포그라운드 액세스를 사용 설정함" + "시스템에서 설정된 권한" @@ -95,6 +96,22 @@ "사용 권한 없음" "앱 권한 사용" "%1$s 전" + "허용" + "항상 허용" + "앱 사용 중에만 허용" + "거부" + "%1$s 권한" + "%2$s%1$s 액세스 권한" + "%3$s 전에 %1$s 앱이 %2$s에 액세스했습니다." + + + "자세한 권한 사용 내역 보기" + + + + + + %s 1일 @@ -111,4 +128,44 @@ %s 1초 + "<b>%1$s</b>을(를) %2$s(으)로 사용하시겠습니까?" + "%1$s 대신 <b>%1$s</b>을(를) %2$s(으)로 사용하시겠습니까?" + + + + + + + + + + + "전화 앱" + "SMS 앱" + "브라우저 앱" + "갤러리 앱" + "음악 앱" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml index 6473de201..4b9b32079 100644 --- a/res/values-ky/strings.xml +++ b/res/values-ky/strings.xml @@ -61,6 +61,7 @@ "Фондук режимде дайындарга мүмкүнчүлүк алуу админ тарабынан өчүрүлгөн" "Фондук режимде дайындарга мүмкүнчүлүк алуу админ тарабынан иштетилген" "Активдүү режимде мүмкүнчүлүк алуу админ тарабынан иштетилген" + "Тутум аркылуу жөндөлгөн уруксаттар" @@ -95,6 +96,22 @@ "Уруксаттар колдонулган жок" "Колдонмонун уруксаттарын пайдалануу" "%1$s мурун" + "Уруксат берүү" + "Бардык учурда уруксат берүү" + "Колдонмо пайдаланылып жаткан учурда гана уруксат берүү" + "Жок" + "%1$s дайындарына уруксаттар" + "%2$s үчүн %1$s дайындарына кирүү" + "%1$s %2$s дайындарыңызга %3$s мурун кирген." + + + "Уруксаттардын колдонулушун чоо-жайы менен көрүү" + + + + + + %s күн 1 күн @@ -111,4 +128,44 @@ %s секунд 1 секунд + "<b>%1$s</b> колдонмосу %2$s катары пайдаланылсынбы?" + "<b>%1$s</b> <b>%1$s</b> колдонмосунун ордуна %2$s катары пайдаланылсынбы?" + + + + + + + + + + + "¨Телефон\" колдонмосу" + "\"SMS\" колдонмосу" + "\"Серепчи\" колдонмосу" + "Галерея колдонмосу" + "Музыка колдонмосу" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-lo/strings.xml b/res/values-lo/strings.xml index e5026a5f0..35ac1225a 100644 --- a/res/values-lo/strings.xml +++ b/res/values-lo/strings.xml @@ -61,6 +61,7 @@ "ຜູ້ເບິ່ງແຍງລະບົບໄດ້ປິດການເຂົ້າເຖິງພື້ນຫຼັງໄວ້ແລ້ວ" "ຜູ້ເບິ່ງແຍງລະບົບໄດ້ເປີດການເຂົ້າເຖິງພື້ນຫຼັງໄວ້ແລ້ວ" "ຜູ້ເບິ່ງແຍງລະບົບໄດ້ເປີດການເຂົ້າເຖິງພື້ນໜ້າໄວ້ແລ້ວ" + "ລະບົບກຳນົດສິດອະນຸຍາດໄວ້ແລ້ວ" @@ -95,6 +96,22 @@ "ບໍ່ມີການນຳໃຊ້ສິດອະນຸຍາດ" "ການໃຊ້ສິດອະນຸຍາດແອັບ" "%1$s ກ່ອນ" + "ອະນຸຍາດ" + "ອະນຸຍາດຕະຫຼອດເວລາ" + "ອະນຸຍາດສະເພາະເມື່ອມີການໃຊ້ແອັບ" + "ປະຕິເສດ" + "ສິດອະນຸຍາດ %1$s" + "ການເຂົ້າເຖິງ %1$s ສຳລັບ %2$s" + "%1$s ເຂົ້າເຖິງ %2$s ຂອງທ່ານເມື່ອ %3$sກ່ອນ." + + + "ເບິ່ງການໃຊ້ສິດອະນຸຍາດແບບລະອຽດ" + + + + + + %s ມື້ 1 ມື້ @@ -111,4 +128,44 @@ %s ວິ​ນາ​ທີ 1 ວິນາທີ + "ໃຊ້ <b>%1$s</b> ເປັນ %2$s ຂອງທ່ານບໍ?" + "ໃຊ້ <b>%1$s</b> ແທນ <b>%1$s</b> ເປັນ %2$s ຂອງທ່ານບໍ?" + + + + + + + + + + + "ແອັບໂທລະສັບ" + "ແອັບ SMS" + "ແອັບໂປຣແກຣມທ່ອງເວັບ" + "ແອັບຄັງ" + "ແອັບເພງ" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml index e658b3a9b..5662edd65 100644 --- a/res/values-lt/strings.xml +++ b/res/values-lt/strings.xml @@ -63,6 +63,7 @@ "Prieigą fone išjungė administratorius" "Prieigą fone įgalino administratorius" "Prieigą priekiniame plane įgalino administratorius" + "Leidimą nustatė sistemą" @@ -97,6 +98,22 @@ "Leidimai nenaudoti" "Programos leidimų naudojimas" "Prieš %1$s" + "Leisti" + "Leisti visą laiką" + "Leisti, tik kai programa naudojama" + "Atmesti" + "Leidimas: %1$s" + "Programos „%2$s“ prieiga prie %1$s" + "Programa „%1$s“ prieš %3$s pasiekė: %2$s." + + + "Žiūrėti išsamią leidimų naudojimo informaciją" + + + + + + %s diena %s dienos @@ -121,4 +138,44 @@ %s sekundės %s sekundžių + "Naudoti programą <b>%1$s</b> kaip %2$s?" + "Naudoti programą <b>%1$s</b> vietoj <b>%1$s</b> kaip %2$s?" + + + + + + + + + + + "Telefono programa" + "SMS programa" + "Naršyklės programa" + "Galerijos programa" + "Muzikos programa" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml index ce54dcb93..70e343b64 100644 --- a/res/values-lv/strings.xml +++ b/res/values-lv/strings.xml @@ -62,6 +62,7 @@ "Administrators atspējoja piekļuvi fonā" "Administrators iespējoja piekļuvi fonā" "Administrators iespējoja piekļuvi priekšplānā" + "Sistēmas iestatīta atļauja" @@ -96,6 +97,22 @@ "Nav lietota neviena atļauja" "Lietotņu atļauju lietojums" "Pirms %1$s" + "Atļaut" + "Vienmēr atļaut" + "Atļaut tikai lietotnes izmantošanas laikā" + "Neatļaut" + "Atļauja: %1$s" + "%1$s: lietotnes %2$s piekļuve" + "%1$s piekļuva jūsu atļaujai %2$s pirms: %3$s." + + + "Skatīt detalizētu informāciju par atļauju lietojumu" + + + + + + %s dienu %s diena @@ -116,4 +133,44 @@ %s sekunde %s sekundes + "Vai lietotni <b>%1$s</b> izmantot kā jūsu lietotni %2$s?" + "Vai lietotni <b>%1$s</b> izmantot kā jūsu lietotni %2$s (lietotnes %1$s vietā)?" + + + + + + + + + + + "Lietotne Tālrunis" + "Īsziņu lietotne" + "Pārlūkprogrammas lietotne" + "Galerijas lietotne" + "Mūzikas lietotne" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml index bdb3bbdd2..959feb1c2 100644 --- a/res/values-mk/strings.xml +++ b/res/values-mk/strings.xml @@ -61,6 +61,7 @@ "Пристапот во заднина е оневозможен од администраторот" "Пристапот во заднина е овозможен од администраторот" "Пристапот во преден план е овозможен од администраторот" + "Дозвола поставена од системот" @@ -95,6 +96,22 @@ "Не се користени дозволи" "Дозволи за апликација" "Пред %1$s" + "Дозволи" + "Дозволи цело време" + "Дозволи само додека се користи апликацијата" + "Одбиј" + "Пристап до %1$s" + "Пристап до %1$s за %2$s" + "%1$s пристапи до %2$s пред %3$s." + + + "Прегледајте го деталното користење на дозволите" + + + + + + %s ден %s дена @@ -111,4 +128,44 @@ %s секунда %s секунди + "Дали да се користи <b>%1$s</b> како ваш %2$s?" + "Дали да се користи <b>%1$s</b> наместо <b>%1$s</b> како ваш %2$s?" + + + + + + + + + + + "Апликација Телефон" + "Апликација за SMS" + "Прелистувач" + "Апликација за галерија" + "Апликација за музика" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml index ed48556cf..ea4381a5d 100644 --- a/res/values-ml/strings.xml +++ b/res/values-ml/strings.xml @@ -61,6 +61,7 @@ "പശ്ചാത്തല ആക്‌സസ് അഡ്‌മിൻ പ്രവർത്തനരഹിതമാക്കി" "പശ്ചാത്തല ആക്‌സസ് അഡ്‌മിൻ പ്രവർത്തനക്ഷമമാക്കി" "പൂർവ്വതല ആക്‌സസ് അഡ്‌മിൻ പ്രവർത്തനക്ഷമമാക്കി" + "സിസ്‌റ്റം, അനുമതി സജ്ജീകരിച്ചു" @@ -95,6 +96,22 @@ "അനുമതി ഉപയോഗങ്ങളൊന്നുമില്ല" "ആപ്പ് അനുമതികളുടെ ഉപയോഗം" "%1$s മുമ്പ്" + "അനുവദിക്കുക" + "ഏതുസമയത്തും അനുവദിക്കുക" + "ആപ്പ് ഉപയോഗത്തിലുള്ളപ്പോൾ മാത്രം അനുവദിക്കുക" + "നിരസിക്കുക" + "%1$s അനുമതി" + "%2$s-നായുള്ള %1$s ആക്‌സസ്" + "%1$s നിങ്ങളുടെ %2$s, %3$s മുമ്പ് ആക്‌സസ് ചെയ്‌തു." + + + "അനുമതികളുടെ വിശദമായ ഉപയോഗം കാണുക" + + + + + + %s ദിവസം ഒരു ദിവസം @@ -111,4 +128,44 @@ %s സെക്കൻഡ് ഒരു സെക്കൻഡ് + "<b>%1$s</b> എന്നതിനെ നിങ്ങളുടെ %2$s ആയി ഉപയോഗിക്കണോ?" + "<b>%1$s</b> എന്നതിന് പകരം <b>%1$s</b> എന്നത്, നിങ്ങളുടെ %2$s ആയി ഉപയോഗിക്കണോ?" + + + + + + + + + + + "ഫോൺ ആപ്പ്" + "SMS ആപ്പ്" + "ബ്രൗസർ ആപ്പ്" + "ഗാലറി ആപ്പ്" + "സംഗീത ആപ്പ്" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml index c5c302f19..571c353c1 100644 --- a/res/values-mn/strings.xml +++ b/res/values-mn/strings.xml @@ -61,6 +61,7 @@ "Админ арын хэсгийн хандалтыг идэвхгүй болгосон" "Админ арын хэсгийн хандалтыг идэвхжүүлсэн" "Админ дэлгэц дээрх хандалтыг идэвхжүүлсэн" + "Системээс тохируулсан зөвшөөрөл" @@ -95,6 +96,22 @@ "Зөвшөөрлийн хэрэглээ алга" "Аппын зөвшөөрлийн ашиглалт" "%1$s-н өмнө" + "Зөвшөөрөх" + "Ямар ч үед зөвшөөрөх" + "Зөвхөн аппыг ашиглаж байх үед зөвшөөрөх" + "Татгалзах" + "%1$s-н зөвшөөрөл" + "%2$s%1$s-н хандалт" + "%1$s таны %2$s%3$s-н өмнө хандсан байна." + + + "Зөвшөөрлийн дэлгэрэнгүй ашиглалтыг харах" + + + + + + %s өдөр 1 өдөр @@ -111,4 +128,44 @@ %s секунд 1 секунд + "Та <b>%1$s</b>-г өөрийн %2$s-р ашиглах үү?" + "Та <b>%1$s</b>-г <b>%1$s</b>-н оронд өөрийн %2$s-р ашиглах үү?" + + + + + + + + + + + "Гар утасны апп" + "SMS апп" + "Хөтөч апп" + "Галерейны апп" + "Хөгжмийн апп" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml index 432c9c858..946d3d42d 100644 --- a/res/values-mr/strings.xml +++ b/res/values-mr/strings.xml @@ -61,6 +61,7 @@ "प्रशासकाने बॅकग्राउंड अॅक्सेस बंद केला आहे" "प्रशासकाने बॅकग्राउंड अॅक्सेस सुरू केला आहे" "प्रशासकाने फोरग्राउंड अॅक्सेस सुरू केला आहे" + "सिस्टमद्वारे परवानगी सेट केली आहे" @@ -95,6 +96,22 @@ "वापराची परवानगी नाही" "अॅप परवानग्यांचा वापर" "%1$s पूर्वी" + "अनुमती द्या" + "सर्व वेळी अनुमती द्या" + "फक्त अॅप वापरत असताना अनुमती द्या" + "नकार द्या" + "%1$s परवानगी" + "%1$s साठी %2$s अॅक्सेस केली" + "%1$s ने तुमची %2$s %3$s पूर्वी अॅक्सेस केली." + + + "परवानग्यांचा वापर तपशीलवार पाहा" + + + + + + %s दिवस %s दिवस @@ -111,4 +128,44 @@ %s सेकंद %s सेकंद + "तुमचे %2$s म्हणून <b>%1$s</b> वापरायचे आहे का?" + "तुमचे %2$s म्हणून <b>%1$s</b> ऐवजी <b>%1$s</b> वापरायचे आहे का?" + + + + + + + + + + + "फोन अॅप" + "एसएमएस अॅप" + "ब्राउझर अॅप" + "गॅलरी अॅप" + "म्युझिक अॅप" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml index c945ad0e8..27cc5fefb 100644 --- a/res/values-ms/strings.xml +++ b/res/values-ms/strings.xml @@ -61,6 +61,7 @@ "Akses latar belakang dilumpuhkan oleh pentadbir" "Akses latar belakang didayakan oleh pentadbir" "Akses latar depan didayakan oleh pentadbir" + "Kebenaran ditetapkan oleh sistem" @@ -95,6 +96,22 @@ "Tiada penggunaan kebenaran" "Penggunaan kebenaran apl" "%1$s yang lalu" + "Benarkan" + "Benarkan sepanjang masa" + "Benarkan hanya semasa apl sedang digunakan" + "Tolak" + "Kebenaran %1$s" + "Akses %1$s untuk %2$s" + "%1$s mengakses %2$s anda %3$s yang lalu." + + + "Lihat penggunaan kebenaran terperinci" + + + + + + %s hari 1 hari @@ -111,4 +128,44 @@ %s saat 1 saat + "Gunakan <b>%1$s</b> sebagai %2$s anda?" + "Gunakan <b>%1$s</b> dan bukannya <b>%1$s</b> sebagai %2$s anda?" + + + + + + + + + + + "Apl Telefon" + "Apl SMS" + "Apl penyemak imbas" + "Apl Galeri" + "Apl Muzik" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml index 61cc790df..269771461 100644 --- a/res/values-my/strings.xml +++ b/res/values-my/strings.xml @@ -61,6 +61,7 @@ "နောက်ကွယ်၌ အသုံးပြုခွင့်ကို စီမံခန့်ခွဲသူက ပိတ်ထားသည်" "နောက်ကွယ်၌ အသုံးပြုခွင့်ကို စီမံခန့်ခွဲသူက ဖွင့်ထားသည်" "မျက်နှာပေါ်၌ အသုံးပြုခွင့်ကို စီမံခန့်ခွဲသူက ဖွင့်ထားသည်" + "စနစ်က သတ်မှတ်ထားသော ခွင့်ပြုချက်" @@ -95,6 +96,22 @@ "မည်သည့်ခွင့်ပြုချက်မှ မသုံးပါ" "အက်ပ်ခွင့်ပြုချက် အသုံးပြုမှု" "ပြီးခဲ့သည့် %1$s က" + "ခွင့်ပြုရန်" + "အမြဲ ခွင့်ပြုရန်" + "အက်ပ်အသုံးပြုချိန်တွင်သာ ခွင့်ပြုရန်" + "ငြင်းပယ်ရန်" + "%1$s ခွင့်ပြုချက်" + "%2$s အတွက် %1$s ဝင်သုံးခွင့်" + "%1$s က သင်၏ %2$s ကို ပြီးခဲ့သော %3$s က ဝင်သုံးထားသည်။" + + + "ခွင့်ပြုချက်များ အသုံးပြုမှု အသေးစိတ်ကို ကြည့်ရန်" + + + + + + %s ရက် ၁ ရက် @@ -111,4 +128,44 @@ %s စက္ကန့် ၁ စက္ကန့် + "<b>%1$s</b> ကို သင့် %2$s အဖြစ် အသုံးပြုမလား။" + "<b>%1$s</b> အစား <b>%1$s</b> ကို သင့် %2$s အဖြစ် အသုံးပြုမလား။" + + + + + + + + + + + "ဖုန်းအက်ပ်" + "SMS အက်ပ်" + "ဘရောင်ဇာ အက်ပ်" + "ပုံပြခန်းအက်ပ်" + "တေးဂီတ အက်ပ်" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml index d6d80fba6..69aff41d8 100644 --- a/res/values-nb/strings.xml +++ b/res/values-nb/strings.xml @@ -61,6 +61,7 @@ "Administratoren har slått av tilgang i bakgrunnen" "Administratoren har slått på tilgang i bakgrunnen" "Administratoren har slått på tilgang i forgrunnen" + "Tillatelse er angitt av systemet" @@ -95,6 +96,22 @@ "Ingen bruk av tillatelsen" "Bruk av apptillatelser" "for %1$s siden" + "Tillat" + "Tillat hele tiden" + "Bare tillat mens appen er i bruk" + "Avvis" + "%1$s-tillatelse" + "%1$s-tilgang for %2$s" + "%1$s har brukt %2$s for %3$s siden." + + + "Vis detaljert bruk av tillatelser" + + + + + + %s dager 1 dag @@ -111,4 +128,44 @@ %s sekunder 1 sekund + "Vil du bruke <b>%1$s</b> som %2$s?" + "Vil du bruke <b>%1$s</b> i stedet for <b>%1$s</b> som %2$s?" + + + + + + + + + + + "Telefon-app" + "SMS-app" + "Nettleserapp" + "Galleri-appen" + "Musikk-appen" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml index 2d315611c..2b3bc6de5 100644 --- a/res/values-ne/strings.xml +++ b/res/values-ne/strings.xml @@ -61,6 +61,7 @@ "प्रशासकले पृष्ठभूमिको प‍हुँच असक्षम पार्नुभएको छ" "प्रशासकले पृष्ठभूमिको प‍हुँच सक्षम पार्नुभएको छ" "प्रशासकले अग्रभूमिको पहुँच सक्षम पार्नुभएको छ" + "प्रणालीले सेट गरेको अनुमति" @@ -95,6 +96,22 @@ "उपयोगको अनुमति छैन" "अनुप्रयोगको अनुमतिको उपयोग" "%1$s पहिले" + "अनुमति दिनुहोस्" + "सधैँ अनुमति दिनुहोस्" + "अनुप्रयोग प्रयोग भएको बेलामा मात्र अनुमति दिनुहोस्‌" + "अस्वीकार गर्नुहोस्‌" + "%1$s अनुमति" + "%2$s का लागि %1$s को पहुँँच" + "%1$s ले %3$s पहिले तपाईंको %2$s माथि पहुँच राख्यो।" + + + "अनुमतिको विस्तृत उपयोग हेर्नुहोस्" + + + + + + %s दिन १ दिन @@ -111,4 +128,44 @@ %s सेकेन्ड १ सेकेन्ड + "<b>%1$s</b> तपाईंको %2$s का रूपमा प्रयोग गर्ने हो?" + "<b>%1$s</b> को सट्टा तपाईंको %2$s का रूपमा <b>%1$s</b> प्रयोग गर्ने हो?" + + + + + + + + + + + "फोन अनुप्रयोग" + "SMS अनुप्रयोग" + "ब्राउजर अनुप्रयोग" + "ग्यालरी अनुप्रयोग" + "सङ्गीत अनुप्रयोग" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml index 14e907c40..1c22f2a14 100644 --- a/res/values-nl/strings.xml +++ b/res/values-nl/strings.xml @@ -61,6 +61,7 @@ "Achtergrondtoegang uitgeschakeld door beheerder" "Achtergrondtoegang ingeschakeld door beheerder" "Voorgrondtoegang ingeschakeld door beheerder" + "Machtiging ingesteld door systeem" @@ -95,6 +96,22 @@ "Geen gebruik van machtigingen" "Gebruik van app-machtigingen" "%1$s geleden" + "Toestaan" + "Altijd toestaan" + "Alleen toestaan terwijl de app wordt gebruikt" + "Weigeren" + "%1$s-machtiging" + "Toegang tot %1$s voor %2$s" + "%1$s heeft %3$s geleden toegang tot je %2$s gehad." + + + "Gedetailleerd machtigingsgebruik weergeven" + + + + + + %s dagen 1 dag @@ -111,4 +128,44 @@ %s seconden 1 seconde + "<b>%1$s</b> gebruiken als je %2$s?" + "<b>%1$s</b> in plaats van <b>%1$s</b> gebruiken als je %2$s?" + + + + + + + + + + + "Telefoon-app" + "Sms-app" + "Browser-app" + "Galerij-app" + "Muziek-app" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml index c70a806b0..833bb4cbf 100644 --- a/res/values-or/strings.xml +++ b/res/values-or/strings.xml @@ -61,6 +61,7 @@ "ବ୍ୟବସ୍ଥାପକଙ୍କ ଦ୍ୱାରା ପୃଷ୍ଠଭୂମି ଆକ୍ସେସ୍‌ ଅକ୍ଷମ କରାଯାଇଛି" "ବ୍ୟବସ୍ଥାପକଙ୍କ ଦ୍ୱାରା ପୃଷ୍ଠଭୂମି ଆକ୍ସେସ୍‌ ସକ୍ଷମ କରାଯାଇଛି" "ବ୍ୟବସ୍ଥାପକଙ୍କ ଦ୍ୱାରା ସମ୍ମୁଖଭାଗ ଆକ୍ସେସ୍‌ ସକ୍ଷମ କରାଯାଇଛି" + "ସିଷ୍ଟମ୍‍ ଦ୍ବାରା ଅନୁମତି ସେଟ୍‍ ହୋଇଛି" @@ -95,6 +96,22 @@ "ବ୍ୟବହାର ପାଇଁ କୌଣସି ଅନୁମତି ନାହିଁ" "ଆପ୍‍ ଅନୁମତି ବ୍ୟବହାର" "%1$s ପୂର୍ବେ" + "ଅନୁମତି ଦିଅନ୍ତୁ" + "ସଦାବେଳେ ପାଇଁ ଅନୁମତି ଦିଅନ୍ତୁ" + "ଆପ୍‍ ବ୍ୟବହାରରେ ରହିଥିବା ବେଳେ କେବଳ ଅନୁମତି କରନ୍ତୁ" + "ଖାରଜ କରନ୍ତୁ" + "%1$s ଅନୁମତି" + "%1$s %2$s ପାଇଁ ଆକ୍ସେସ୍‍ କରନ୍ତୁ" + "%1$s %3$s ପୂର୍ବେ ଆପଣଙ୍କ %2$s ଆକ୍ସେସ୍‍ କରିିିିଥିଲେ।" + + + "ବିସ୍ତୃତ ଅନୁମତି ବ୍ୟବହାର ଦେଖନ୍ତୁ" + + + + + + %s ଦିନ 1 ଦିନ @@ -111,4 +128,44 @@ %s ସେକେଣ୍ଡ 1 ସେକେଣ୍ଡ + "ଆପଣଙ୍କ %2$s ଭାବରେ <b>%1$s</b> ବ୍ୟବହାର କରିବେ?" + "ଆପଣଙ୍କ %2$s ଭାବରେ <b>%1$s</b> ପରିବର୍ତ୍ତେ <b>%1$s</b> ବ୍ୟବହାର କରିବେ?" + + + + + + + + + + + "ଫୋନ୍‌ ଆପ୍‌" + "SMS ଆପ୍‌" + "ବ୍ରାଉଜର୍‌ ଆପ୍‌" + "Gallery ଆପ୍‍" + "Music ଆପ୍‍" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml index 7150da0ac..e0d563d99 100644 --- a/res/values-pa/strings.xml +++ b/res/values-pa/strings.xml @@ -61,6 +61,7 @@ "ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਬੈਕਗ੍ਰਾਊਂਡ ਪਹੁੰਚ ਨੂੰ ਬੰਦ ਕੀਤਾ ਗਿਆ" "ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਬੈਕਗ੍ਰਾਊਂਡ ਪਹੁੰਚ ਨੂੰ ਚਾਲੂ ਕੀਤਾ ਗਿਆ" "ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਫੋਰਗ੍ਰਾਊਂਡ ਪਹੁੰਚ ਨੂੰ ਚਾਲੂ ਕੀਤਾ ਗਿਆ" + "ਇਜਾਜ਼ਤ ਸਿਸਟਮ ਵੱਲੋਂ ਸੈੱਟ ਕੀਤੀ ਜਾਂਦੀ ਹੈ" @@ -95,6 +96,22 @@ "ਕੋਈ ਇਜਾਜ਼ਤ ਨਹੀਂ ਵਰਤੀ ਗਈ" "ਐਪ ਇਜਾਜ਼ਤਾਂ ਵਰਤੋ" "%1$s ਪਹਿਲਾਂ" + "ਕਰਨ ਦਿਓ" + "ਹਰ ਵੇਲੇ ਕਰਨ ਦਿਓ" + "ਸਿਰਫ਼ ਐਪ ਵਰਤੇ ਜਾਣ ਵੇਲੇ ਕਰਨ ਦਿਓ" + "ਅਸਵੀਕਾਰ ਕਰੋ" + "%1$s ਇਜਾਜ਼ਤ" + "%2$s ਲਈ %1$s ਪਹੁੰਚ" + "%1$s ਨੇ %3$s ਪਹਿਲਾਂ ਤੁਹਾਡੇ %2$s ਤੱਕ ਪਹੁੰਚ ਕੀਤੀ।" + + + "ਇਜਾਜ਼ਤਾਂ ਦੀ ਵਰਤੋਂ ਵੇਰਵੇ-ਸਹਿਤ ਦੇਖੋ" + + + + + + %s ਦਿਨ %s ਦਿਨ @@ -111,4 +128,44 @@ %s ਸਕਿੰਟ %s ਸਕਿੰਟ + "ਕੀ <b>%1$s</b> ਨੂੰ ਆਪਣੀ %2$s ਵਜੋਂ ਵਰਤਣਾ ਹੈ?" + "ਕੀ <b>%1$s</b> ਦੀ ਬਜਾਏ <b>%1$s</b> ਨੂੰ ਆਪਣੀ %2$s ਵਜੋਂ ਵਰਤਣਾ ਹੈ?" + + + + + + + + + + + "ਫ਼ੋਨ ਐਪ" + "SMS ਐਪ" + "ਬ੍ਰਾਊਜ਼ਰ ਐਪ" + "ਗੈਲਰੀ ਐਪ" + "ਸੰਗੀਤ ਐਪ" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml index a4fcc3470..52f187355 100644 --- a/res/values-pl/strings.xml +++ b/res/values-pl/strings.xml @@ -63,6 +63,7 @@ "Dostęp w tle wyłączony przez administratora" "Dostęp w tle włączony przez administratora" "Dostęp na pierwszym planie włączony przez administratora" + "Uprawnienie ustawione przez system" @@ -97,6 +98,22 @@ "Brak użycia uprawnień" "Użycie uprawnień aplikacji" "%1$s temu" + "Zezwól" + "Zawsze zezwalaj" + "Zezwalaj tylko podczas używania aplikacji" + "Odmów" + "Uprawnienie dostępu do: %1$s" + "Dostęp do: %1$s dla aplikacji %2$s" + "Aplikacja %1$s użyła dostępu do: %2$s %3$s temu." + + + "Wyświetl szczegółowe użycie uprawnień" + + + + + + %s dni %s dni @@ -121,4 +138,44 @@ %s sekundy 1 sekunda + "Użyć aplikacji <b>%1$s</b> jako: %2$s?" + "Użyć aplikacji <b>%1$s</b> zamiast aplikacji <b>%1$s</b> jako: %2$s?" + + + + + + + + + + + "Telefon" + "Aplikacja do SMS-ów" + "Przeglądarka" + "Aplikacja Galeria" + "Aplikacja Muzyka" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-pt-rBR/strings.xml b/res/values-pt-rBR/strings.xml index e193ebaad..324157c40 100644 --- a/res/values-pt-rBR/strings.xml +++ b/res/values-pt-rBR/strings.xml @@ -61,6 +61,7 @@ "Acesso em segundo plano desativado pelo administrador" "Acesso em segundo plano ativado pelo administrador" "Acesso em primeiro plano ativado pelo administrador" + "Permissão definida pelo sistema" @@ -95,6 +96,22 @@ "Nenhum uso de permissões" "Uso de permissões do app" "Há %1$s" + "Permitir" + "Permitir o tempo todo" + "Permitir apenas enquanto o app estiver em uso" + "Negar" + "Permissão de %1$s" + "Acesso à permissão de %1$s para o app %2$s" + "O app %1$s acessou sua permissão de %2$s %3$s atrás." + + + "Ver uso detalhado das permissões" + + + + + + %s dia %s dias @@ -111,4 +128,44 @@ %s segundo %s segundos + "Usar o app <b>%1$s</b> como seu %2$s?" + "Usar o app <b>%1$s</b> em vez de <b>%1$s</b> como seu %2$s?" + + + + + + + + + + + "App Telefone" + "App de SMS" + "App de navegação" + "App de galeria" + "App de música" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml index ec8df84ff..511de8c5c 100644 --- a/res/values-pt-rPT/strings.xml +++ b/res/values-pt-rPT/strings.xml @@ -61,6 +61,7 @@ "Acesso em segundo plano desativado pelo administrador" "Acesso em segundo plano ativado pelo administrador" "Acesso em primeiro plano ativado pelo administrador" + "Autorização definida pelo sistema" @@ -95,6 +96,18 @@ "Autorizações não utilizadas" "Utiliz. de autoriz. da app" "Há %1$s" + "Permitir" + "Permitir sempre" + "Permitir apenas enquanto a aplicação está a ser utilizada" + "Recusar" + "Autorização para o(a) %1$s" + "Acesso ao(à) %1$s para a aplicação %2$s." + "A aplicação %1$s acedeu ao(à) %2$s%3$s." + "A aplicação %1$s não acedeu à sua %2$s." + "Ver utilização de autorizações detalhada" + "Acesso mais recente há %1$s." + "Permitidas" + "Recusadas" %s dias 1 dia @@ -111,4 +124,34 @@ %s segundos 1 segundo + "Pretende utilizar <b>%1$s</b> como %2$s?" + "Pretende utilizar <b>%1$s</b> em vez de <b>%1$s</b> como %2$s?" + + + + + + + "Aplicações predefinidas" + "Sem aplicações predefinidas" + "Aplicação Telefone" + "Aplicação de SMS" + "Aplicação de navegador" + "Aplicação de galeria" + "Aplicação de música" + "O programador da aplicação afirma que os seus dados podem ser:" + "Se não gostar da forma como o programador desta aplicação está a utilizar os seus dados, pode recusar a autorização." + "Carregados para a nuvem." + "Carregados para a nuvem quando o autorizar explicitamente." + "Partilhados com anunciantes ou empresas." + "Partilhados com anunciantes ou empresas quando o autorizar explicitamente." + "Utilizados para rentabilização." + "Utilizados para rentabilização quando o autorizar explicitamente." + "Guardados e analisados para sempre." + "Guardados e analisados durante o período especificado por si." + + Guardados e analisados durante %s semanas. + Guardados e analisados durante 1 semana. + + "O programador da aplicação não especificou de que forma a aplicação utiliza os seus dados." diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml index e193ebaad..324157c40 100644 --- a/res/values-pt/strings.xml +++ b/res/values-pt/strings.xml @@ -61,6 +61,7 @@ "Acesso em segundo plano desativado pelo administrador" "Acesso em segundo plano ativado pelo administrador" "Acesso em primeiro plano ativado pelo administrador" + "Permissão definida pelo sistema" @@ -95,6 +96,22 @@ "Nenhum uso de permissões" "Uso de permissões do app" "Há %1$s" + "Permitir" + "Permitir o tempo todo" + "Permitir apenas enquanto o app estiver em uso" + "Negar" + "Permissão de %1$s" + "Acesso à permissão de %1$s para o app %2$s" + "O app %1$s acessou sua permissão de %2$s %3$s atrás." + + + "Ver uso detalhado das permissões" + + + + + + %s dia %s dias @@ -111,4 +128,44 @@ %s segundo %s segundos + "Usar o app <b>%1$s</b> como seu %2$s?" + "Usar o app <b>%1$s</b> em vez de <b>%1$s</b> como seu %2$s?" + + + + + + + + + + + "App Telefone" + "App de SMS" + "App de navegação" + "App de galeria" + "App de música" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml index d0396f88f..372f0e591 100644 --- a/res/values-ro/strings.xml +++ b/res/values-ro/strings.xml @@ -62,6 +62,7 @@ "Accesul la fundal dezactivat de administrator" "Accesul la fundal activat de administrator" "Accesul la prim-plan activat de administrator" + "Permisiune setată de sistem" @@ -96,6 +97,22 @@ "Nicio permisiune folosită" "Utilizare permisiuni pentru aplicație" "Acum %1$s" + "Permiteți" + "Permiteți întotdeauna" + "Permiteți numai când aplicația este folosită" + "Refuzați" + "Permisiune %1$s" + "Acces la %1$s pentru aplicația %2$s" + "Aplicația %1$s a accesat %2$s acum %3$s." + + + "Afișați utilizarea detaliată a permisiunilor" + + + + + + %s zile %s de zile @@ -116,4 +133,44 @@ %s de secunde O secundă + "Folosiți <b>%1$s</b> ca %2$s?" + "Folosiți <b>%1$s</b> în loc de <b>%1$s</b> ca %2$s?" + + + + + + + + + + + "Aplicația Telefon" + "Aplicația SMS" + "Aplicația Browser" + "Aplicația Galerie" + "Aplicația Muzică" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index 0cd641b19..c6a52989c 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -63,6 +63,7 @@ "Доступ в фоновом режиме отключен администратором" "Доступ в фоновом режиме включен администратором" "Доступ в активном режиме включен администратором" + "Разрешение предоставлено системой" @@ -97,6 +98,22 @@ "Разрешения не использовались" "Использование разрешений" "%1$s назад" + "Разрешить" + "Разрешить в любом режиме" + "Разрешить только в активном режиме" + "Запретить" + "Разрешение \"%1$s\"" + "Доступ к разрешению \"%1$s\" для приложения \"%2$s\"." + "Приложение \"%1$s\" получило доступ к разрешению \"%2$s\" %3$s назад." + + + "Показать подробную информацию об использовании разрешений" + + + + + + %s день %s дня @@ -121,4 +138,44 @@ %s сек. %s сек. + "Использовать приложение <b>%1$s</b> в роли \"%2$s\"?" + "Использовать приложение <b>%1$s</b> вместо <b>%1$s</b> в роли \"%2$s\"?" + + + + + + + + + + + "Приложение для звонков" + "Приложение для SMS" + "Браузер" + "Галерея" + "Музыка" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml index 31fd8085b..4ffc78542 100644 --- a/res/values-si/strings.xml +++ b/res/values-si/strings.xml @@ -61,6 +61,7 @@ "පසුබිම් ප්‍රවේශය පරිපාලක විසින් අබල කර ඇත" "පසුබිම් ප්‍රවේශය පරිපාලක විසින් සබල කර ඇත" "පෙරබිම් ප්‍රවේශය පරිපාලක විසින් සබල කර ඇත" + "පද්ධතිය මගින් සකසන අවසරය" @@ -95,6 +96,22 @@ "අවසර භාවිත නැත" "යෙදුම් අවසර භාවිතය" "%1$sකට පෙර" + "ඉඩ දෙන්න" + "සැම විටම ඉඩ දෙන්න" + "යෙදුම භාවිතයේදී පමණක් ඉඩ දෙන්න" + "ප්‍රතික්ෂේප කර." + "%1$s අවසරය" + "%2$s සඳහා %1$s ප්‍රවේශය" + "%1$s ඔබේ %2$s %3$sකට පෙර පිවිසියා." + + + "විස්තරාත්මක අවසර භාවිතය බලන්න" + + + + + + දින %s දින %s @@ -111,4 +128,44 @@ තත්පර %s තත්පර %s + "ඔබේ %2$s ලෙස <b>%1$s</b> භාවිත කරන්නද?" + "<b>%1$s</b> වෙනුවට ඔබේ %2$s ලෙස <b>%1$s</b> භාවිත කරන්නද?" + + + + + + + + + + + "දුරකථන යෙදුම" + "කෙටි පණිවුඩ යෙදුම" + "බ්‍රවුසර යෙදුම" + "Gallery යෙදුම" + "සංගීත යෙදුම" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml index 51a1b0c2e..de4b445d3 100644 --- a/res/values-sk/strings.xml +++ b/res/values-sk/strings.xml @@ -63,6 +63,7 @@ "Prístup na pozadí bol zakázaný správcom" "Prístup na pozadí bol povolený správcom" "Prístup na popredí bol povolený správcom" + "Povolenie nastavené systémom" @@ -97,6 +98,22 @@ "Žiadne využitie povolení" "Využitie povolení aplikácie" "pred %1$s" + "Povoliť" + "Povoliť po celý čas" + "Povoliť iba počas používania aplikácie" + "Odmietnuť" + "Povolenie %1$s" + "Prístup k %1$s pre %2$s" + "Aplikácia %1$s použila %2$s pred %3$s." + + + "Zobraziť podrobné údaje o využití povolení" + + + + + + %s dni %s dňa @@ -121,4 +138,44 @@ %s sekúnd 1 sekunda + "Chcete aplikáciu <b>%1$s</b> použiť ako %2$s?" + "Chcete použiť aplikáciu <b>%1$s</b> (namiesto aplikácie <b>%1$s</b>) ako %2$s?" + + + + + + + + + + + "Aplikácia Telefón" + "Aplikácia pre SMS a MMS" + "Prehliadač" + "Aplikácia Galéria" + "Aplikácia Hudba" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml index 6e4ba2010..72f085888 100644 --- a/res/values-sl/strings.xml +++ b/res/values-sl/strings.xml @@ -63,6 +63,7 @@ "Skrbnik je onemogočil dostop iz ozadja" "Skrbnik je omogočil dostop iz ozadja" "Skrbnik je omogočil dostop v ospredju" + "Dovoljenje je nastavil sistem" @@ -97,6 +98,22 @@ "Ni uporabe dovoljenj" "Uporaba dovoljenj aplikacije" "pred %1$s" + "Dovoli" + "Vedno dovoli" + "Dovoli samo, ko je aplikacija v uporabi" + "Zavrni" + "Dovoljenje %1$s" + "Dostop do dovoljenja %1$s za aplikacijo %2$s" + "Aplikacija %1$s je do dovoljenja %2$s dostopala pred %3$s." + + + "Podroben prikaz uporabe dovoljenj" + + + + + + %s dnevom %s dnevoma @@ -121,4 +138,44 @@ %s sekundami %s sekundami + "Želite za vlogo %2$s uporabljati aplikacijo <b>%1$s</b>?" + "Želite za vlogo %2$s uporabljati aplikacijo <b>%1$s</b> namesto aplikacije <b>%1$s</b>?" + + + + + + + + + + + "Aplikacija Telefon" + "Aplikacija za SMS-je" + "Brskalnik" + "Aplikacija Galerija" + "Aplikacija Glasba" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml index 357fa615f..99a8a0013 100644 --- a/res/values-sq/strings.xml +++ b/res/values-sq/strings.xml @@ -61,6 +61,7 @@ "Qasja në sfond është e çaktivizuar nga administratori" "Qasja në sfond është e aktivizuar nga administratori" "Qasja në planin e parë është e aktivizuar nga administratori" + "Autorizimi i caktuar nga sistemi" @@ -95,6 +96,22 @@ "Nuk ka përdorime të lejeve" "Përdorimi i lejeve të apl." "%1$s më parë" + "Lejo" + "Lejo gjithmonë" + "Lejo vetëm kur aplikacioni është në përdorim" + "Refuzo" + "Autorizim te %1$s" + "Qasje te %1$s për %2$s" + "%1$s pati qasje te %2$s %3$s më parë." + + + "Shiko përdorimin e detajuar të autorizimeve" + + + + + + %s ditë 1 ditë @@ -111,4 +128,44 @@ %s sekonda 1 sekondë + "Të përdoret <b>%1$s</b> si %2$s?" + "Të përdoret <b>%1$s</b> në vend të <b>%1$s</b> si %2$s?" + + + + + + + + + + + "Aplikacioni \"Telefoni\"" + "Aplikacioni për SMS" + "Aplikacioni për shfletim" + "Aplikacioni i galerisë" + "Aplikacioni i muzikës" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml index ff71a164c..233411a26 100644 --- a/res/values-sr/strings.xml +++ b/res/values-sr/strings.xml @@ -62,6 +62,7 @@ "Администратор је онемогућио приступ у позадини" "Администратор је омогућио приступ у позадини" "Администратор је омогућио приступ у првом плану" + "Систем је подесио дозволу" @@ -96,6 +97,22 @@ "Дозволе нису коришћене" "Коришћење дозвола за аплик." "пре %1$s" + "Дозволи" + "Дозволи увек" + "Дозволи само док се апликација користи" + "Одбиј" + "Дозвола %1$s" + "Приступ дозволи %1$s за апликацију %2$s" + "Апликација %1$s је приступила дозволи %2$s пре %3$s." + + + "Прегледајте детаљне дозволе за коришћење" + + + + + + %s дан %s дана @@ -116,4 +133,44 @@ %s секунде %s секунди + "Желите ли да <b>%1$s</b> буде %2$s?" + "Желите ли да <b>%1$s</b> буде %2$s уместо <b>%1$s</b>?" + + + + + + + + + + + "Апликација Телефон" + "Апликација за SMS" + "Апликација прегледача" + "Апликација Галерија" + "Апликација Музика" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml index 3106f31c5..575d6e89f 100644 --- a/res/values-sv/strings.xml +++ b/res/values-sv/strings.xml @@ -61,6 +61,7 @@ "Åtkomst i bakgrunden har inaktiverats av administratören" "Åtkomst i bakgrunden har aktiverats av administratören" "Åtkomst i förgrunden har aktiverats av administratören" + "Behörigheten har angetts av systemet" @@ -95,6 +96,22 @@ "Ingen behörighetsanvändning" "Appens behörighetsanvändning" "För %1$s sedan" + "Tillåt" + "Tillåt alltid" + "Tillåt bara när appen används" + "Neka" + "Behörighet till %1$s" + "Åtkomst till %1$s för %2$s" + "%1$s använde din %2$s för %3$s sedan." + + + "Visa utförlig information om behörighetsanvändning" + + + + + + %s dagar 1 dag @@ -111,4 +128,44 @@ %s sekunder 1 sekund + "Vill du använda <b>%1$s</b> som %2$s?" + "Vill du använda <b>%1$s</b> i stället för <b>%1$s</b> som %2$s?" + + + + + + + + + + + "Appen Telefon" + "Sms-app" + "Webbläsarapp" + "Appen Galleri" + "Appen Musik" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml index b6e6589db..20ce13ddb 100644 --- a/res/values-sw/strings.xml +++ b/res/values-sw/strings.xml @@ -61,6 +61,7 @@ "Msimamizi amezima kipengele cha ufikiaji wa chinichini" "Msimamizi amewasha kipengele cha ufikiaji wa chinichini" "Msimamizi amezima kipengele cha ufikiaji wakati programu inatumika" + "Ruhusa imewekwa na mfumo" @@ -95,6 +96,22 @@ "Hakuna matumizi ya ruhusa" "Matumizi ya idhini za programu" "%1$s zilizopita" + "Ruhusu" + "Ruhusu kila wakati" + "Ruhusu tu wakati programu inatumika" + "Kataa" + "Ruhusa ya %1$s" + "Ruhusa ya %1$s ya kufikia %2$s" + "%1$s imefikia %2$s yako %3$s zilizopita." + + + "Angalia matumizi ya ruhusa za kina" + + + + + + Siku %s Siku 1 @@ -111,4 +128,44 @@ Sekunde %s Sekunde 1 + "Ungependa kutumia <b>%1$s</b> kama programu yako ya %2$s?" + "Ungependa kutumia <b>%1$s</b> badala ya <b>%1$s</b> kama programu yako ya %2$s?" + + + + + + + + + + + "Programu ya simu" + "Programu ya SMS" + "Programu ya kivinjari" + "Programu ya matunzio" + "Programu ya muziki" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml index eb53a7a54..afe5187a2 100644 --- a/res/values-ta/strings.xml +++ b/res/values-ta/strings.xml @@ -61,6 +61,7 @@ "\'பின்புல அணுகலை\' நிர்வாகி முடக்கியுள்ளார்" "\'பின்புல அணுகலை’ நிர்வாகி இயக்கியுள்ளார்" "\'முன்புல அணுகலை\' நிர்வாகி இயக்கியுள்ளார்" + "சிஸ்டத்தால் அமைக்கப்பட்டுள்ள அனுமதி" @@ -95,6 +96,22 @@ "உபயோகிக்கப்படாத அனுமதிகள்" "ஆப்ஸ் அனுமதிகளை உபயோகித்தல்" "%1$s முன்பு" + "அனுமதி" + "அனைத்து நேரங்களிலும் அனுமதி" + "ஆப்ஸ் உபயோகத்தில் இருக்கும்போது மட்டும் அனுமதி" + "நிராகரி" + "%1$s என்பதற்கான அனுமதி" + "%2$s ஆப்ஸிற்கான %1$s அணுகல்" + "%3$s நேரத்திற்கு முன்பு %1$s ஆப்ஸ் உங்கள் %2$sஐ அணுகியது." + + + "அனுமதிகளின் உபயோகம் தொடர்பான விவரங்களைக் காட்டு" + + + + + + %s நாட்கள் 1 நாள் @@ -111,4 +128,44 @@ %s விநாடிகள் 1 விநாடி + "<b>%1$s</b> என்பதை %2$s ஆகப் பயன்படுத்தவா?" + "<b>%1$s</b> என்பதை <b>%1$s</b> என்பதற்குப் பதிலாக %2$s ஆகப் பயன்படுத்தவா?" + + + + + + + + + + + "மொபைல் ஆப்ஸ்" + "மெசேஜ் ஆப்ஸ்" + "உலாவி ஆப்ஸ்" + "கேலரி ஆப்ஸ்" + "மியூசிக் ஆப்ஸ்" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml index 505783206..af2285e68 100644 --- a/res/values-te/strings.xml +++ b/res/values-te/strings.xml @@ -61,6 +61,7 @@ "నిర్వాహకులు నేపథ్య యాక్సెస్‌ను నిలిపివేసారు" "నిర్వాహకులు నేపథ్య యాక్సెస్‌ను అనుమతించారు" "నిర్వాహకులు స్క్రీన్ యాక్సెస్‌ను అనుమతించారు" + "సిస్టమ్ ద్వారా అనుమతి సెట్ చేయబడింది" @@ -95,6 +96,22 @@ "అనుమతి వినియోగాలేవీ లేవు" "యాప్ అనుమతుల వినియోగం" "%1$s క్రితం" + "అనుమతించు" + "అన్ని సమయాలలో అనుమతించు" + "యాప్ వినియోగంలో ఉన్నప్పుడు మాత్రమే అనుమతించు" + "తిరస్కరించు" + "%1$s అనుమతి" + "%2$s కోసం %1$s యాక్సెస్" + "%1$s మీ %2$sని %3$s క్రితం యాక్సెస్ చేసింది." + + + "వివరణాత్మక అనుమతుల వినియోగాన్ని చూడండి" + + + + + + %s రోజులు 1 రోజు @@ -111,4 +128,44 @@ %s సెకన్లు 1 సెకను + "<b>%1$sని </b> మీ %2$sగా వాడాలా?" + "<b>%1$s బదులుగా %1$sని </b> మీ %2$sగా వాడాలా?" + + + + + + + + + + + "ఫోన్ యాప్" + "SMS యాప్" + "బ్రౌజర్ యాప్" + "గ్యాలరీ యాప్‌" + "సంగీత యాప్" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml index 6e4d6944f..54a260a14 100644 --- a/res/values-th/strings.xml +++ b/res/values-th/strings.xml @@ -61,6 +61,7 @@ "ปิดใช้การเข้าถึงเมื่ออยู่เบื้องหลังโดยผู้ดูแลระบบ" "เปิดใช้การเข้าถึงเมื่ออยู่เบื้องหลังโดยผู้ดูแลระบบ" "เปิดใช้การเข้าถึงเมื่ออยู่เบื้องหน้าโดยผู้ดูแลระบบ" + "สิทธิ์ที่กำหนดโดยระบบ" @@ -95,6 +96,22 @@ "ไม่มีการใช้สิทธิ์" "การใช้สิทธิ์ของแอป" "%1$sที่ผ่านมา" + "อนุญาต" + "อนุญาตตลอด" + "อนุญาตเมื่อมีการใช้แอปเท่านั้น" + "ปฏิเสธ" + "สิทธิ์เกี่ยวกับ%1$s" + "สิทธิ์การเข้าถึง%1$sของ %2$s" + "%1$s เข้าถึง%2$sของคุณเมื่อ %3$s ที่ผ่านมา" + + + "ดูรายละเอียดการใช้สิทธิ์" + + + + + + %s วัน 1 วัน @@ -111,4 +128,44 @@ %s วินาที 1 วินาที + "ใช้ <b>%1$s</b> เป็น%2$s ไหม" + "ใช้ <b>%1$s</b> แทนที่ <b>%1$s</b> เป็น%2$s ไหม" + + + + + + + + + + + "แอปโทรศัพท์" + "แอป SMS" + "แอปเบราว์เซอร์" + "แอปแกลเลอรี" + "แอปเพลง" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml index 11baf41e1..ccbae9165 100644 --- a/res/values-tl/strings.xml +++ b/res/values-tl/strings.xml @@ -61,6 +61,7 @@ "Na-disable ng admin ang access habang nasa background" "Na-enable ng admin ang access habang nasa background" "Na-enable ng admin ang access habang nasa foreground" + "System ang nagtakda ng pahintulot" @@ -95,6 +96,22 @@ "Walang paggamit ng pahintulot" "Paggamit ng pahintulot sa app" "%1$s na ang nakalipas" + "Payagan" + "Payagan sa lahat ng oras" + "Payagan lang habang ginagamit ang app" + "Tanggihan" + "%1$s na pahintulot" + "%1$s na access para sa %2$s" + "Na-access ng %1$s ang iyong %2$s %3$s ang nakalipas." + + + "Tingnan ang detalyadong paggamit sa mga pahintulot" + + + + + + %s araw %s na araw @@ -111,4 +128,44 @@ %s segundo %s na segundo + "Gamitin ang <b>%1$s</b> bilang iyong %2$s?" + "Gamitin ang <b>%1$s</b> sa halip na ang <b>%1$s</b> bilang iyong %2$s?" + + + + + + + + + + + "Phone app" + "SMS app" + "Browser app" + "Gallery app" + "Music app" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml index b16861cda..bb7386306 100644 --- a/res/values-tr/strings.xml +++ b/res/values-tr/strings.xml @@ -61,6 +61,7 @@ "Arka planda erişim yönetici tarafından devre dışı bırakıldı" "Arka planda erişim yönetici tarafından etkinleştirildi" "Ön planda erişim yönetici tarafından etkinleştirildi" + "Sistem tarafından ayarlanan izin" @@ -95,6 +96,22 @@ "İzin kullanılmadı" "Uygulama izinleri kullanımı" "%1$s önce" + "İzin ver" + "Her zaman izin ver" + "Yalnızca uygulama kullanılırken izin ver" + "Reddet" + "%1$s izni" + "%2$s için %1$s erişimi" + "%1$s %3$s önce cihazınızın %2$s özelliğine erişti." + + + "Ayrıntılı izin kullanımını göster" + + + + + + %s gün 1 gün @@ -111,4 +128,44 @@ %s saniye 1 saniye + "<b>%1$s</b> uygulaması %2$s olarak kullanılsın mı?" + "%2$s olarak <b>%1$s</b> yerine <b>%1$s</b> kullanılsın mı?" + + + + + + + + + + + "Telefon uygulaması" + "SMS uygulaması" + "Tarayıcı uygulaması" + "Galeri uygulaması" + "Müzik uygulaması" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml index c5286e6e6..27962d4ff 100644 --- a/res/values-uk/strings.xml +++ b/res/values-uk/strings.xml @@ -63,6 +63,7 @@ "Адміністратор вимкнув доступ у фоновому режимі" "Адміністратор увімкнув доступ у фоновому режимі" "Адміністратор увімкнув доступ в активному режимі" + "Дозвіл надала система" @@ -97,6 +98,22 @@ "Дозволи не використовувалися" "Використання дозволів додатка" "%1$s тому" + "Дозволити" + "Дозволяти завжди" + "Дозволяти, лише коли додаток використовується" + "Заборонити" + "Дозвіл – %1$s" + "Доступ (%1$s) для додатка %2$s" + "Додаток %1$s отримав доступ %3$s тому (%2$s)." + + + "Переглянути детальну інформацію про використання дозволів" + + + + + + %s день %s дні @@ -121,4 +138,44 @@ %s секунд %s секунди + "Чи має <b>%1$s</b> працювати як %2$s?" + "Чи має <b>%1$s</b> працювати як %2$s замість додатка <b>%1$s</b>?" + + + + + + + + + + + "Додаток Телефон" + "Додаток для SMS" + "Додаток для веб-перегляду" + "Додаток Галерея" + "Додаток Музика" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml index 959899a3b..69a2f0739 100644 --- a/res/values-ur/strings.xml +++ b/res/values-ur/strings.xml @@ -61,6 +61,7 @@ "منتظم نے پس منظر کی رسائی غیر فعال کر دی ہے" "منتظم نے پس منظر کی رسائی فعال کر دی ہے" "منتظم نے پیش منظر کی رسائی فعال کر دی ہے" + "اجازت سسٹم نے سیٹ کی ہے" @@ -95,6 +96,22 @@ "اجازت کا استعمال نہیں ہوا ہے" "ایپ کی اجازتوں کا استعمال" "%1$s پہلے" + "اجازت دیں" + "ہر وقت اجازت دیں" + "صرف اسی وقت اجازت دیں جب ایپ استعمال کی جا رہی ہو" + "مسترد کریں" + "%1$s کی اجازت" + "%1$s نے %2$s کیلئے رسائی حاصل کی" + "%1$s نے %3$s پہلے %2$s تک رسائی حاصل کی۔" + + + "تفصیلی اجازتوں کا استعمال دیکھیں" + + + + + + %s دن 1 دن @@ -111,4 +128,44 @@ %s سیکنڈ 1 سیکنڈ + "‏کیا آپ <b>%1$s</b> کا استعمال اپنے %2$s کے طور پر کرنا چاہتے ہیں؟" + "‏کیا آپ <b>%1$s</b> کی بجائے <b>%1$s</b> کا استعمال اپنے %2$s کے طور پر کرنا چاہتے ہیں؟" + + + + + + + + + + + "فون ایپ" + "‏SMS ایپ" + "براؤزر ایپ" + "گیلری ایپ" + "موسیقی ایپ" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml index e816d329c..fb1e4c236 100644 --- a/res/values-uz/strings.xml +++ b/res/values-uz/strings.xml @@ -61,6 +61,7 @@ "Fon rejimida kirish administrator tomonidan taqiqlangan" "Fon rejimida kirish administrator tomonidan yoqilgan" "Faol rejimda kirish administrator tomonidan yoqilgan" + "Ruxsatni tizim sozlagan" @@ -95,6 +96,22 @@ "Ruxsatlardan foydalanilmagan" "Ilovalar uchun ruxsatlar" "%1$s oldin" + "Ruxsat berish" + "Har qanday rejimda ruxsat berish" + "Faqat faol rejimda ruxsat berish" + "Rad etish" + "%1$s ruxsati" + "%2$s uchun %1$s ruxsati" + "%1$s %3$s oldin %2$s ruxsatidan foydalandi." + + + "Ruxsatlardan foydalanish haqida batafsil axborotni ochish" + + + + + + %s kun 1 kun @@ -111,4 +128,44 @@ %s soniya 1 soniya + "<b>%1$s</b> ilovasidan %2$s rolida foydalanasizmi?" + "<b>%1$s</b> oʻrniga %1$s ilovasidan %2$s rolida foydalanasizmi?" + + + + + + + + + + + "Telefon ilovasi" + "SMS ilovasi" + "Brauzer ilovasi" + "Galereya ilovasi" + "Musiqa ilovasi" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml index 482f11b65..9cc4803d3 100644 --- a/res/values-vi/strings.xml +++ b/res/values-vi/strings.xml @@ -61,6 +61,7 @@ "Quản trị viên đã tắt quyền truy cập khi ở nền sau" "Quản trị viên đã bật quyền truy cập khi ở nền sau" "Quản trị viên đã bật quyền truy cập khi ở nền trước" + "Quyền do hệ thống đặt" @@ -95,6 +96,22 @@ "Không sử dụng quyền" "Sử dụng quyền ứng dụng" "%1$s trước" + "Cho phép" + "Luôn cho phép" + "Chỉ cho phép khi đang sử dụng ứng dụng" + "Từ chối" + "Quyền %1$s" + "Quyền truy cập vào %1$s của %2$s" + "%1$s đã truy cập vào %2$s %3$s trước." + + + "Xem mức sử dụng quyền chi tiết" + + + + + + %s ngày 1 ngày @@ -111,4 +128,44 @@ %s giây 1 giây + "Bạn có muốn dùng <b>%1$s</b> làm %2$s của mình không?" + "Bạn có muốn dùng <b>%1$s</b> thay vì <b>%1$s</b> làm %2$s của mình không?" + + + + + + + + + + + "Ứng dụng điện thoại" + "Ứng dụng SMS" + "Ứng dụng trình duyệt" + "Ứng dụng thư viện" + "Ứng dụng âm nhạc" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml index 8019cdf7d..e94da0e14 100644 --- a/res/values-zh-rCN/strings.xml +++ b/res/values-zh-rCN/strings.xml @@ -61,6 +61,7 @@ "管理员已停用后台使用权" "管理员已启用后台使用权" "管理员已启用前台使用权" + "系统设置的权限" @@ -95,6 +96,22 @@ "没有使用此权限的应用" "应用权限使用情况" "%1$s前" + "允许" + "始终允许" + "仅在使用该应用期间允许" + "拒绝" + "%1$s权限" + "%2$s%1$s访问权限" + "%1$s %3$s前访问过您的%2$s。" + + + "查看权限使用情况详情" + + + + + + %s 1 天 @@ -111,4 +128,44 @@ %s 1 秒 + "要使用<b>%1$s</b>作为您的%2$s吗?" + "要使用<b>%1$s</b>(而非<b>%1$s</b>)作为您的%2$s吗?" + + + + + + + + + + + "电话应用" + "短信应用" + "浏览器应用" + "图库应用" + "音乐应用" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml index fff6d5538..377eeaed4 100644 --- a/res/values-zh-rHK/strings.xml +++ b/res/values-zh-rHK/strings.xml @@ -61,6 +61,7 @@ "管理員已停用背景存取權" "管理員已啟用背景存取權" "管理員已啟用前景存取權" + "系統設定的權限" @@ -95,6 +96,22 @@ "沒有應用程式使用要求的權限" "應用程式權限使用情況" "%1$s前" + "允許" + "一律允許" + "只在使用應用程式時允許" + "拒絕" + "%1$s權限" + "「%2$s」的%1$s存取權" + "「%1$s」在 %3$s前存取了您的%2$s。" + + + "查看詳細的權限使用情況" + + + + + + %s 1 天 @@ -111,4 +128,44 @@ %s 1 秒 + "要將「%1$s」<b></b>作為%2$s使用嗎?" + "要將「%1$s」<b></b>代替「%1$s」<b></b>作為%2$s使用嗎?" + + + + + + + + + + + "手機應用程式" + "短訊應用程式" + "瀏覽器應用程式" + "相片集應用程式" + "音樂應用程式" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml index 66bd0edb5..545037d80 100644 --- a/res/values-zh-rTW/strings.xml +++ b/res/values-zh-rTW/strings.xml @@ -61,6 +61,7 @@ "管理員已停用背景存取權" "管理員已啟用背景存取權" "管理員已啟用前景存取權" + "系統設定的權限" @@ -95,6 +96,22 @@ "沒有使用此權限的應用程式" "應用程式權限使用情況" "%1$s前" + "允許" + "一律允許" + "僅在使用該應用程式時允許" + "拒絕" + "%1$s權限" + "「%2$s」的%1$s存取權" + "「%1$s」在 %3$s前存取了你的%2$s。" + + + "查看詳細的權限使用情況" + + + + + + %s 1 天 @@ -111,4 +128,44 @@ %s 1 秒 + "要將「%1$s」<b></b>設為你的%2$s嗎?" + "要將你的%2$s從「%1$s」<b></b>改為「%1$s」<b></b>嗎?" + + + + + + + + + + + "「電話」應用程式" + "簡訊應用程式" + "瀏覽器應用程式" + "圖片庫應用程式" + "音樂應用程式" + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml index 057b3f804..21728a2d8 100644 --- a/res/values-zu/strings.xml +++ b/res/values-zu/strings.xml @@ -61,6 +61,7 @@ "Ukufinyelela kwangemuva kukhutshazwe umlawuli" "Ukufinyelela kwangemuva kunikwe amandla umlawuli" "Ukufinyelela kwangaphambili kunikwe amandla umlawuli" + "Imvume esethwe isistimu" @@ -95,6 +96,22 @@ "Akukho ukusetshenziswa kwemvume" "Ukusetshenziswa kwezimvume zohlelo lokusebenza" "%1$s edlule" + "Vumela" + "Vumela sonke isikhathi" + "Vumela kuphela ngenkathi uhlelo lokusebenza lusebenza" + "Phika" + "%1$s imvume" + "%1$s ukufinyelela kwe-%2$s" + "%1$s ufinyelele u-%2$s yakho isikhathi esingu-%3$s esedlule." + + + "Buka ukusetshenziswa kwezimvume ezinemininingwane" + + + + + + %s izinsuku %s izinsuku @@ -111,4 +128,44 @@ %s amasekhondi %s amasekhondi + "Sebenzisa i-<b>%1$s</b> njenge-%2$s yakho?" + "Sebenzisa i-<b>%1$s</b> esikhundleni se-<b>%1$s</b> njenge-%2$s yakho?" + + + + + + + + + + + "Uhlelo lokusebenza lwefoni" + "Uhlelo lokusebenza lwe-SMS" + "Uhlelo lokusebenza lwesiphequluli" + "Uhlelo lokusebenza lwegalari" + "Uhlelo lokusebenza lomculo" + + + + + + + + + + + + + + + + + + + + + + + -- GitLab From 5b06f97b14984074e608b73b2ca27fe87971eac5 Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Thu, 6 Dec 2018 09:21:32 -0800 Subject: [PATCH 175/701] Only re-up if app currently has background location access. Test: atest CtsPermissionTestCases:android.permission.cts.LocationAccessCheckTest (includes a new test that covers this situation) Change-Id: Ibc42c982cca6cb75f12acd00216306d4c48505c7 --- .../service/LocationAccessCheck.java | 64 ++++++++++++------- 1 file changed, 40 insertions(+), 24 deletions(-) diff --git a/src/com/android/packageinstaller/permission/service/LocationAccessCheck.java b/src/com/android/packageinstaller/permission/service/LocationAccessCheck.java index eef1ec316..5ff9c4021 100644 --- a/src/com/android/packageinstaller/permission/service/LocationAccessCheck.java +++ b/src/com/android/packageinstaller/permission/service/LocationAccessCheck.java @@ -16,7 +16,6 @@ package com.android.packageinstaller.permission.service; -import static android.Manifest.permission.ACCESS_BACKGROUND_LOCATION; import static android.Manifest.permission.ACCESS_FINE_LOCATION; import static android.app.AppOpsManager.OPSTR_FINE_LOCATION; import static android.app.NotificationManager.IMPORTANCE_LOW; @@ -408,6 +407,8 @@ public class LocationAccessCheck extends JobService { // Get a random package and resolve package info PackageInfo pkgInfo = null; while (pkgInfo == null) { + throwInterruptedExceptionIfTaskIsCanceledLocked(); + if (packages.isEmpty()) { return; } @@ -435,11 +436,16 @@ public class LocationAccessCheck extends JobService { pkgInfo = packageToNotifyFor.getPackageInfo(this); } catch (PackageManager.NameNotFoundException e) { packages.remove(packageToNotifyFor); + continue; } - createPermissionReminderChannel(packageToNotifyFor.user); + if (!isBackgroundLocationPermissionGranted(pkgInfo)) { + pkgInfo = null; + packages.remove(packageToNotifyFor); + } } + createPermissionReminderChannel(getUserHandleForUid(pkgInfo.applicationInfo.uid)); createNotificationForLocationUser(pkgInfo); } } @@ -575,6 +581,35 @@ public class LocationAccessCheck extends JobService { return null; } + /** + * Check is a package currently has the background access to + * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} or can get it without user + * interaction. + * + * @param pkg The package that might have access. + * + * @return {@code true} iff the app currently has access to the fine background location + */ + private boolean isBackgroundLocationPermissionGranted(@NonNull PackageInfo pkg) { + AppPermissionGroup locationGroup = AppPermissionGroup.create(this, pkg, + ACCESS_FINE_LOCATION, false); + + if (locationGroup == null) { + // All location permissions have been removed from this package + return false; + } else { + AppPermissionGroup locationBgGroup = locationGroup.getBackgroundPermissions(); + Permission locationPerm = locationGroup.getPermission(ACCESS_FINE_LOCATION); + + // Individual permission have been removed + return locationBgGroup != null + && locationPerm != null + && locationBgGroup.hasPermission(locationPerm.getBackgroundPermissionName()) + && locationGroup.areRuntimePermissionsGranted() + && locationBgGroup.areRuntimePermissionsGranted(); + } + } + /** * Go through the list of packages we already shown a notification for and remove those that do * not request fine background location access. @@ -589,6 +624,8 @@ public class LocationAccessCheck extends JobService { ArrayList packagesToRemove = new ArrayList<>(); for (UserPackage userPkg : alreadyNotifiedPkgs) { + throwInterruptedExceptionIfTaskIsCanceledLocked(); + PackageInfo pkgInfo; try { pkgInfo = userPkg.getPackageInfo(this); @@ -597,29 +634,8 @@ public class LocationAccessCheck extends JobService { continue; } - AppPermissionGroup locationGroup = AppPermissionGroup.create(this, pkgInfo, - ACCESS_FINE_LOCATION, false); - throwInterruptedExceptionIfTaskIsCanceledLocked(); - - if (locationGroup == null) { - // All permission of the group have been removed + if (!isBackgroundLocationPermissionGranted(pkgInfo)) { packagesToRemove.add(userPkg); - } else { - Permission fgPerm = locationGroup.getPermission(ACCESS_FINE_LOCATION); - - Permission bgPerm = null; - AppPermissionGroup bgPerms = locationGroup.getBackgroundPermissions(); - if (bgPerms != null) { - bgPerm = bgPerms.getPermission(ACCESS_BACKGROUND_LOCATION); - } - - // Individual permission have been removed - if (fgPerm == null || bgPerm == null - // Permissions are not granted - || !fgPerm.isGranted() || !fgPerm.isAppOpAllowed() - || !bgPerm.isGranted() || !bgPerm.isAppOpAllowed()) { - packagesToRemove.add(userPkg); - } } } -- GitLab From 9df64d4950ce8629a5b0a49673084182957d2ba6 Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Thu, 6 Dec 2018 12:06:15 -0800 Subject: [PATCH 176/701] Start new task for every location switch Test: Clicked on re-up notification while previous switch was still open Change-Id: I577e19e15e2ebe1352b1a0eaead5dd97fbdac44b --- .../permission/service/LocationAccessCheck.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/com/android/packageinstaller/permission/service/LocationAccessCheck.java b/src/com/android/packageinstaller/permission/service/LocationAccessCheck.java index eef1ec316..dd2ffbbdf 100644 --- a/src/com/android/packageinstaller/permission/service/LocationAccessCheck.java +++ b/src/com/android/packageinstaller/permission/service/LocationAccessCheck.java @@ -28,6 +28,7 @@ import static android.content.Intent.EXTRA_PACKAGE_NAME; import static android.content.Intent.EXTRA_PERMISSION_NAME; import static android.content.Intent.EXTRA_UID; import static android.content.Intent.EXTRA_USER; +import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.content.pm.PackageManager.GET_PERMISSIONS; import static android.graphics.Bitmap.Config.ARGB_8888; @@ -758,7 +759,7 @@ public class LocationAccessCheck extends JobService { markAsNotified(context, pkg, user); Intent manageAppPermission = new Intent(context, AppPermissionActivity.class); - manageAppPermission.addFlags(FLAG_ACTIVITY_NEW_TASK); + manageAppPermission.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK); manageAppPermission.putExtra(EXTRA_PERMISSION_NAME, ACCESS_FINE_LOCATION); manageAppPermission.putExtra(EXTRA_PACKAGE_NAME, pkg); manageAppPermission.putExtra(EXTRA_USER, user); -- GitLab From 37e7cb2581171f185fa54e62603459e05b4d4188 Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Thu, 6 Dec 2018 12:39:17 -0800 Subject: [PATCH 177/701] Re-up: Correctly set bitmap and allow multi-line text Test: Looked at re-up Change-Id: I572b65600782080ae11c1aeab36d1cf77f574d21 --- .../permission/service/LocationAccessCheck.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/com/android/packageinstaller/permission/service/LocationAccessCheck.java b/src/com/android/packageinstaller/permission/service/LocationAccessCheck.java index eef1ec316..c187b5247 100644 --- a/src/com/android/packageinstaller/permission/service/LocationAccessCheck.java +++ b/src/com/android/packageinstaller/permission/service/LocationAccessCheck.java @@ -506,7 +506,9 @@ public class LocationAccessCheck extends JobService { Drawable pkgIcon = mPackageManager.getApplicationIcon(pkg.applicationInfo); Bitmap pkgIconBmp = createBitmap(pkgIcon.getIntrinsicWidth(), pkgIcon.getIntrinsicHeight(), ARGB_8888); - pkgIcon.draw(new Canvas(pkgIconBmp)); + Canvas canvas = new Canvas(pkgIconBmp); + pkgIcon.setBounds(0, 0, pkgIcon.getIntrinsicWidth(), pkgIcon.getIntrinsicHeight()); + pkgIcon.draw(canvas); String pkgName = pkg.packageName; UserHandle user = getUserHandleForUid(pkg.applicationInfo.uid); @@ -527,6 +529,8 @@ public class LocationAccessCheck extends JobService { R.string.background_location_access_reminder_notification_title, pkgLabel)) .setContentText(getString( R.string.background_location_access_reminder_notification_content)) + .setStyle(new Notification.BigTextStyle().bigText(getString( + R.string.background_location_access_reminder_notification_content))) .setSmallIcon(R.drawable.ic_signal_location) .setLargeIcon(pkgIconBmp) .setAutoCancel(true) -- GitLab From 6ab8572591f77fee3fdd33e5c5c146efade22976 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Thu, 6 Dec 2018 13:04:09 -0800 Subject: [PATCH 178/701] Allow scrolling in AppPermissionFragment. Wrap the layout in a ScrollView so we can scroll through it in landscape mode. Change-Id: I76c9733446fd8fb659b6d49b688ddfd6cee96732 Fixes: 120613460 Test: Scrolled through the screen in landscape mode. --- res/layout/app_permission.xml | 286 ++++++++++++++++++---------------- 1 file changed, 150 insertions(+), 136 deletions(-) diff --git a/res/layout/app_permission.xml b/res/layout/app_permission.xml index 92edfa1aa..e68f38663 100644 --- a/res/layout/app_permission.xml +++ b/res/layout/app_permission.xml @@ -23,176 +23,190 @@ - - - + + - - + android:orientation="vertical"> + android:orientation="vertical" + android:minHeight="?android:attr/listPreferredItemHeight" + android:paddingStart="?android:attr/listPreferredItemPaddingStart" + android:paddingEnd="?android:attr/listPreferredItemPaddingEnd" + android:background="?android:attr/selectableItemBackground"> - + android:layout_marginTop="@dimen/app_permission_header_margin_top" + android:layout_marginStart="@dimen/app_permission_header_margin_start" + android:textAllCaps="true" + android:textAppearance="?android:attr/textAppearanceSmall" /> + + + + + + + + + + + + + + + + + + + + - - - - - + - - - - - - - - - - - - - - - - - - - + android:layout_height=".75dp" + android:layout_marginTop="@dimen/app_permission_divider_margin_top" + android:layout_marginBottom="@dimen/app_permission_divider_margin_bottom" + android:background="?android:attr/dividerHorizontal"/> + android:orientation="vertical" + android:minHeight="?android:attr/listPreferredItemHeight" + android:paddingStart="?android:attr/listPreferredItemPaddingStart" + android:paddingEnd="?android:attr/listPreferredItemPaddingEnd" + android:background="?android:attr/selectableItemBackground"> + style="@style/FooterText"/> - + android:orientation="vertical"> + + + + + + + + + + + + + + + + - + + style="@style/FooterText" + android:textColor="?android:attr/colorAccent" + android:clickable="true" /> - - - - - + \ No newline at end of file -- GitLab From beb7ba81dbc00729088823925a11ee24f7bcf8a0 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Thu, 6 Dec 2018 09:14:30 -0800 Subject: [PATCH 179/701] Ensure apps and permissions are correctly sorted by the locale. This modifies PermissionAppsFragment and ManagePermissionsFragment to sort the list of apps and permissions in a locale-sensitive way using a Collator. AppPermissionsFragment was already correct because AppPermissionGroup's compareTo method uses a Collator, but at Philip's suggestion I modified the UI element to sort as well to avoid that hidden dependence. Test: See alphabetical ordering of apps and permissions in English and in Spanish for the modified fragments. Change-Id: Ifaaaad711314f755ce23ed911385f083cae8e2b7 --- .../ui/handheld/AppPermissionsFragment.java | 16 +++- .../handheld/ManagePermissionsFragment.java | 14 +++- .../ui/handheld/PermissionAppsFragment.java | 80 ++++++++----------- 3 files changed, 61 insertions(+), 49 deletions(-) diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java index a4b8c631a..112cdee4a 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java @@ -47,6 +47,9 @@ import com.android.packageinstaller.permission.utils.Utils; import com.android.permissioncontroller.R; import com.android.settingslib.HelpUtils; +import java.text.Collator; +import java.util.ArrayList; + /** * Show and manage permission groups for an app. * @@ -61,6 +64,8 @@ public final class AppPermissionsFragment extends SettingsWithHeader { private AppPermissions mAppPermissions; private PreferenceScreen mExtraScreen; + private Collator mCollator; + private boolean mHasConfirmedRevoke; public static AppPermissionsFragment newInstance(String packageName) { @@ -101,6 +106,8 @@ public final class AppPermissionsFragment extends SettingsWithHeader { getActivity().finish(); } }); + mCollator = Collator.getInstance( + getContext().getResources().getConfiguration().getLocales().get(0)); updatePreferences(); } @@ -195,7 +202,14 @@ public final class AppPermissionsFragment extends SettingsWithHeader { extraPerms.setTitle(R.string.additional_permissions); boolean extraPermsAreAllowed = false; - for (AppPermissionGroup group : mAppPermissions.getPermissionGroups()) { + ArrayList groups = new ArrayList<>( + mAppPermissions.getPermissionGroups()); + groups.sort((x, y) -> mCollator.compare(x.getLabel(), y.getLabel())); + allowed.setOrderingAsAdded(true); + denied.setOrderingAsAdded(true); + + for (int i = 0; i < groups.size(); i++) { + AppPermissionGroup group = groups.get(i); if (!Utils.shouldShowPermission(getContext(), group)) { continue; } diff --git a/src/com/android/packageinstaller/permission/ui/handheld/ManagePermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/ManagePermissionsFragment.java index 415257c01..28dd40e71 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/ManagePermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/ManagePermissionsFragment.java @@ -30,7 +30,8 @@ import com.android.packageinstaller.permission.model.PermissionGroups; import com.android.packageinstaller.permission.utils.Utils; import com.android.permissioncontroller.R; -import java.util.List; +import java.text.Collator; +import java.util.ArrayList; /** * Superclass for fragments allowing the user to manage permissions. @@ -44,6 +45,8 @@ abstract class ManagePermissionsFragment extends PermissionsFrameFragment private PermissionGroups mPermissions; + private Collator mCollator; + @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); @@ -54,6 +57,8 @@ abstract class ManagePermissionsFragment extends PermissionsFrameFragment ab.setDisplayHomeAsUpEnabled(true); } mPermissions = new PermissionGroups(getContext(), getActivity().getLoaderManager(), this); + mCollator = Collator.getInstance( + getContext().getResources().getConfiguration().getLocales().get(0)); } @Override @@ -106,7 +111,8 @@ abstract class ManagePermissionsFragment extends PermissionsFrameFragment return null; } - List groups = mPermissions.getGroups(); + ArrayList groups = new ArrayList<>(mPermissions.getGroups()); + groups.sort((x, y) -> mCollator.compare(x.getLabel(), y.getLabel())); PreferenceScreen screen = getPreferenceScreen(); if (screen == null) { screen = getPreferenceManager().createPreferenceScreen(context); @@ -114,10 +120,12 @@ abstract class ManagePermissionsFragment extends PermissionsFrameFragment } else { screen.removeAll(); } + screen.setOrderingAsAdded(true); // Use this to speed up getting the info for all of the PermissionApps below. // Create a new one for each refresh to make sure it has fresh data. - for (PermissionGroup group : groups) { + for (int i = 0; i < groups.size(); i++) { + PermissionGroup group = groups.get(i); boolean isSystemPermission = group.getDeclaringPackage().equals(OS_PKG); if (addSystemPermissions == isSystemPermission) { diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java index 677e401e7..179d5593a 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java @@ -20,6 +20,7 @@ import android.content.Context; import android.content.Intent; import android.graphics.drawable.Drawable; import android.os.Bundle; +import android.util.ArrayMap; import android.util.ArraySet; import android.view.Menu; import android.view.MenuInflater; @@ -40,6 +41,10 @@ import com.android.packageinstaller.permission.utils.Utils; import com.android.permissioncontroller.R; import com.android.settingslib.HelpUtils; +import java.text.Collator; +import java.util.ArrayList; +import java.util.Map; + /** * Show and manage apps which request a single permission group. * @@ -76,6 +81,8 @@ public final class PermissionAppsFragment extends PermissionsFrameFragment imple private Callback mOnPermissionsLoadedListener; + private Collator mCollator; + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -96,6 +103,9 @@ public final class PermissionAppsFragment extends PermissionsFrameFragment imple mPermissionApps = new PermissionApps(getActivity(), groupName, this); mPermissionApps.refresh(true); + mCollator = Collator.getInstance( + getContext().getResources().getConfiguration().getLocales().get(0)); + addPreferencesFromResource(R.xml.allowed_denied); } @@ -183,28 +193,39 @@ public final class PermissionAppsFragment extends PermissionsFrameFragment imple PreferenceCategory allowed = (PreferenceCategory) findPreference("allowed"); PreferenceCategory denied = (PreferenceCategory) findPreference("denied"); - allowed.setOrderingAsAdded(false); - denied.setOrderingAsAdded(false); + allowed.setOrderingAsAdded(true); + denied.setOrderingAsAdded(true); - ArraySet preferencesToRemove = new ArraySet<>(); + Map existingPrefs = new ArrayMap<>(); int numPreferences = allowed.getPreferenceCount(); for (int i = 0; i < numPreferences; i++) { - preferencesToRemove.add(allowed.getPreference(i).getKey()); + Preference preference = allowed.getPreference(i); + existingPrefs.put(preference.getKey(), preference); } + allowed.removeAll(); numPreferences = denied.getPreferenceCount(); for (int i = 0; i < numPreferences; i++) { - preferencesToRemove.add(denied.getPreference(i).getKey()); + Preference preference = denied.getPreference(i); + existingPrefs.put(preference.getKey(), preference); } + denied.removeAll(); if (mExtraScreen != null) { for (int i = 0, n = mExtraScreen.getPreferenceCount(); i < n; i++) { - preferencesToRemove.add(mExtraScreen.getPreference(i).getKey()); + Preference preference = mExtraScreen.getPreference(i); + existingPrefs.put(preference.getKey(), preference); } + mExtraScreen.removeAll(); } mHasSystemApps = false; boolean menuOptionsInvalided = false; - for (PermissionApp app : permissionApps.getApps()) { + ArrayList sortedApps = new ArrayList<>(permissionApps.getApps()); + sortedApps.sort((x, y) -> mCollator.compare(x.getLabel(), y.getLabel())); + + for (int i = 0; i < sortedApps.size(); i++) { + PermissionApp app = sortedApps.get(i); + if (!Utils.shouldShowPermission(getContext(), app.getPermissionGroup())) { continue; } @@ -214,8 +235,11 @@ public final class PermissionAppsFragment extends PermissionsFrameFragment imple } String key = app.getKey(); - preferencesToRemove.remove(key); - Preference existingPref = findExistingPreference(key, allowed, denied); + Preference existingPref = existingPrefs.get(key); + if (existingPref != null) { + // Without this, existing preferences remember their old order. + existingPref.setOrder(Preference.DEFAULT_ORDER); + } boolean isSystemApp = Utils.isSystem(app, mLauncherPkgs); @@ -226,25 +250,18 @@ public final class PermissionAppsFragment extends PermissionsFrameFragment imple } if (isSystemApp && !isTelevision && !mShowSystem) { - if (existingPref != null) { - existingPref.getParent().removePreference(existingPref); - } continue; } PreferenceCategory category = app.areRuntimePermissionsGranted() ? allowed : denied; if (existingPref != null) { - // If the granted status has changed, move the permission to the new category. - if (category != existingPref.getParent()) { - existingPref.getParent().removePreference(existingPref); - category.addPreference(existingPref); - } + category.addPreference(existingPref); continue; } Preference pref = new PermissionUsagePreference(context, app.getPermissionGroup()); - pref.setKey(app.getKey()); + pref.setKey(key); pref.setIcon(app.getIcon()); pref.setTitle(app.getLabel()); @@ -259,7 +276,6 @@ public final class PermissionAppsFragment extends PermissionsFrameFragment imple } if (mExtraScreen != null) { - preferencesToRemove.remove(KEY_SHOW_SYSTEM_PREFS); Preference pref = allowed.findPreference(KEY_SHOW_SYSTEM_PREFS); int grantedCount = 0; @@ -293,13 +309,6 @@ public final class PermissionAppsFragment extends PermissionsFrameFragment imple grantedCount, mExtraScreen.getPreferenceCount())); } - for (String key : preferencesToRemove) { - Preference pref = findExistingPreference(key, allowed, denied); - if (pref != null) { - pref.getParent().removePreference(pref); - } - } - setLoading(false /* loading */, true /* animate */); if (mOnPermissionsLoadedListener != null) { @@ -307,25 +316,6 @@ public final class PermissionAppsFragment extends PermissionsFrameFragment imple } } - private Preference findExistingPreference(String key, PreferenceCategory allowed, - PreferenceCategory denied) { - Preference preference = allowed.findPreference(key); - if (preference != null) { - return preference; - } - preference = denied.findPreference(key); - if (preference != null) { - return preference; - } - if (mExtraScreen != null) { - preference = mExtraScreen.findPreference(key); - if (preference != null) { - return preference; - } - } - return null; - } - public static class SystemAppsFragment extends PermissionsFrameFragment implements Callback { PermissionAppsFragment mOuterFragment; -- GitLab From bbea9aa2d047f7a1b76c8a7f9d22d88e51619c22 Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Thu, 6 Dec 2018 16:58:40 -0800 Subject: [PATCH 180/701] Send group-name instead of permission-name The AppPermissionActivity interface has change. Hence change the user in LocationAccessCheck too. Test: Clicked on LocationAccessCheck notification and verified that this leads to the AppPermissionActivity Change-Id: I27ae0ceba233616fcd7a05d480ef7c0e49f7d9b0 --- .../permission/service/LocationAccessCheck.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/com/android/packageinstaller/permission/service/LocationAccessCheck.java b/src/com/android/packageinstaller/permission/service/LocationAccessCheck.java index b74585954..54ce89b9d 100644 --- a/src/com/android/packageinstaller/permission/service/LocationAccessCheck.java +++ b/src/com/android/packageinstaller/permission/service/LocationAccessCheck.java @@ -47,6 +47,7 @@ import static com.android.packageinstaller.Constants.PERMISSION_REMINDER_CHANNEL import static com.android.packageinstaller.Constants.PREFERENCES_FILE; import static com.android.packageinstaller.permission.utils.LocationUtils.isNetworkLocationProvider; import static com.android.packageinstaller.permission.utils.Utils.OS_PKG; +import static com.android.packageinstaller.permission.utils.Utils.getGroupOfPlatformPermission; import static com.android.packageinstaller.permission.utils.Utils.getParcelableExtraSafe; import static com.android.packageinstaller.permission.utils.Utils.getStringExtraSafe; import static com.android.packageinstaller.permission.utils.Utils.getSystemServiceSafe; @@ -764,7 +765,8 @@ public class LocationAccessCheck extends JobService { Intent manageAppPermission = new Intent(context, AppPermissionActivity.class); manageAppPermission.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK); - manageAppPermission.putExtra(EXTRA_PERMISSION_NAME, ACCESS_FINE_LOCATION); + manageAppPermission.putExtra(EXTRA_PERMISSION_NAME, + getGroupOfPlatformPermission(ACCESS_FINE_LOCATION)); manageAppPermission.putExtra(EXTRA_PACKAGE_NAME, pkg); manageAppPermission.putExtra(EXTRA_USER, user); -- GitLab From 7b87cf14accc867f8332bc848c75d7f12cf1449c Mon Sep 17 00:00:00 2001 From: Baligh Uddin Date: Thu, 6 Dec 2018 19:43:44 -0800 Subject: [PATCH 181/701] Set MIN_SDK to 28 Bug: 120419012 --- Android.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/Android.mk b/Android.mk index 90675fba2..64df055d3 100644 --- a/Android.mk +++ b/Android.mk @@ -36,6 +36,7 @@ LOCAL_STATIC_JAVA_LIBRARIES := \ LOCAL_PACKAGE_NAME := PermissionController LOCAL_SDK_VERSION := system_current +LOCAL_MIN_SDK_VERSION := 28 LOCAL_PRIVILEGED_MODULE := true LOCAL_CERTIFICATE := platform -- GitLab From d218f88b9be0c694e831aa99aaa58d07ded6b9ee Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Fri, 7 Dec 2018 19:25:14 -0800 Subject: [PATCH 182/701] Give androidx-lifecycle provider authority a unique name So that the authority does not clash with other authorities using the androidx lifecycle components. Test: Looked at manifest after build via "aapt l -a" atest PermissionHostTests Change-Id: I1919bb62d178dd9c3fb15ebae550cf65907c3863 --- AndroidManifest.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 45e32f961..9c0feaf67 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1,5 +1,6 @@ @@ -40,6 +41,13 @@ android:defaultToDeviceProtectedStorage="true" android:directBootAware="true"> + + -- GitLab From 67232cfb524a538db8b727b3bbf57ef9264f076f Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Fri, 7 Dec 2018 08:23:24 -0800 Subject: [PATCH 183/701] Add permission justification icons. This adds an icon for each permission justification. The icons are shown only when the accompanying text for that justification is shown. Bug:63532550 Bug: 111207567 Test: Hardcode justifications, see icons. Test: See icons in dark mode. Change-Id: I4032639d7994a9dba92a5b674d8132dec811d45d --- res/drawable/ic_attach_money_black.xml | 31 +++++++ res/drawable/ic_backup.xml | 32 +++++++ res/drawable/ic_business_black.xml | 29 +++++++ res/drawable/ic_timelapse_black.xml | 29 +++++++ res/layout/app_permission.xml | 84 ++++++++++++++++--- res/values/styles.xml | 9 +- .../ui/handheld/AppPermissionFragment.java | 33 +++++--- 7 files changed, 221 insertions(+), 26 deletions(-) create mode 100644 res/drawable/ic_attach_money_black.xml create mode 100644 res/drawable/ic_backup.xml create mode 100644 res/drawable/ic_business_black.xml create mode 100644 res/drawable/ic_timelapse_black.xml diff --git a/res/drawable/ic_attach_money_black.xml b/res/drawable/ic_attach_money_black.xml new file mode 100644 index 000000000..47985b0c5 --- /dev/null +++ b/res/drawable/ic_attach_money_black.xml @@ -0,0 +1,31 @@ + + + + + + \ No newline at end of file diff --git a/res/drawable/ic_backup.xml b/res/drawable/ic_backup.xml new file mode 100644 index 000000000..2e5578f01 --- /dev/null +++ b/res/drawable/ic_backup.xml @@ -0,0 +1,32 @@ + + + + + + \ No newline at end of file diff --git a/res/drawable/ic_business_black.xml b/res/drawable/ic_business_black.xml new file mode 100644 index 000000000..9686b8e4f --- /dev/null +++ b/res/drawable/ic_business_black.xml @@ -0,0 +1,29 @@ + + + + + + \ No newline at end of file diff --git a/res/drawable/ic_timelapse_black.xml b/res/drawable/ic_timelapse_black.xml new file mode 100644 index 000000000..1b14a6c6e --- /dev/null +++ b/res/drawable/ic_timelapse_black.xml @@ -0,0 +1,29 @@ + + + + + + \ No newline at end of file diff --git a/res/layout/app_permission.xml b/res/layout/app_permission.xml index e68f38663..8c98948fc 100644 --- a/res/layout/app_permission.xml +++ b/res/layout/app_permission.xml @@ -160,29 +160,89 @@ android:layout_height="wrap_content" android:orientation="vertical"> - + android:gravity="center_vertical" + android:orientation="horizontal" + style="@style/FooterListEntry"> + + + + + + - + android:gravity="center_vertical" + android:orientation="horizontal" + style="@style/FooterListEntry"> + + + + + + - + android:gravity="center_vertical" + android:orientation="horizontal" + style="@style/FooterListEntry"> + + + + + + - + android:gravity="center_vertical" + android:orientation="horizontal" + style="@style/FooterListEntry"> + + + + + + diff --git a/res/values/styles.xml b/res/values/styles.xml index fb6e77b5c..8ac7c03a1 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -37,8 +37,15 @@ + + diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java index 36d8f88ca..43fe2c68d 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java @@ -463,32 +463,38 @@ public class AppPermissionFragment extends PermissionsFrameFragment { // Show/hide or set the text of the various text views. ((TextView) root.requireViewById(R.id.justification_header)).setText( context.getString(R.string.permission_justification_header)); - setUsageText(root.requireViewById(R.id.justification_sent_off_device), sentOffDevice, + setUsageText(root.requireViewById(R.id.justification_sent_off_device), + root.requireViewById(R.id.justification_sent_off_device_text), sentOffDevice, R.string.permission_justification_data_sent_off_device, R.string.permission_justification_data_sent_off_device_user_triggered, context); setUsageText(root.requireViewById(R.id.justification_shared_with_third_party), + root.requireViewById(R.id.justification_shared_with_third_party_text), sharedWithThirdParty, R.string.permission_justification_data_shared_with_third_party, R.string.permission_justification_data_shared_with_third_party_user_triggered, context); setUsageText(root.requireViewById(R.id.justification_used_for_monetization), + root.requireViewById(R.id.justification_used_for_monetization_text), usedForMonetization, R.string.permission_justification_data_used_for_monetization, R.string.permission_justification_data_used_for_monetization_user_triggered, context); - TextView retentionTextView = root.requireViewById(R.id.justification_retention); if (retention == UsesPermissionInfo.RETENTION_NOT_RETAINED) { - retentionTextView.setVisibility(View.GONE); + root.requireViewById(R.id.justification_retention).setVisibility(View.GONE); } else if (retention == UsesPermissionInfo.RETENTION_USER_SELECTED) { - retentionTextView.setText(context.getString( - R.string.permission_justification_data_retention_user_selected)); + ((TextView) root.requireViewById(R.id.justification_retention_text)).setText( + context.getString( + R.string.permission_justification_data_retention_user_selected)); } else if (retention == UsesPermissionInfo.RETENTION_SPECIFIED) { - retentionTextView.setText(context.getResources().getQuantityString( - R.plurals.permission_justification_data_retention_specified, retentionWeeks, - retentionWeeks)); + ((TextView) root.requireViewById(R.id.justification_retention_text)).setText( + context.getResources().getQuantityString( + R.plurals.permission_justification_data_retention_specified, + retentionWeeks, + retentionWeeks)); } else { - retentionTextView.setText(context.getString( - R.string.permission_justification_data_retention_unlimited)); + ((TextView) root.requireViewById(R.id.justification_retention_text)).setText( + context.getString( + R.string.permission_justification_data_retention_unlimited)); } } } @@ -528,6 +534,7 @@ public class AppPermissionFragment extends PermissionsFrameFragment { /** * Set the text of the given view to one of the given values or hide it if necessary. * + * @param container the view that contains the given text view. * @param textView the TextView to change * @param value the value that controls which text to use * @param yesStrId the resId of the string to use if the usage is allowed @@ -535,10 +542,10 @@ public class AppPermissionFragment extends PermissionsFrameFragment { * triggered actions. * @param context the context */ - private void setUsageText(TextView textView, int value, int yesStrId, int userTriggeredStrId, - Context context) { + private void setUsageText(View container, TextView textView, int value, int yesStrId, + int userTriggeredStrId, Context context) { if (value == UsesPermissionInfo.USAGE_NO) { - textView.setVisibility(View.GONE); + container.setVisibility(View.GONE); } else if (value == UsesPermissionInfo.USAGE_USER_TRIGGERED) { textView.setText(context.getString(userTriggeredStrId)); } else { -- GitLab From e714983905821e0dd7491b6805501d505ed22120 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Fri, 7 Dec 2018 10:06:21 -0800 Subject: [PATCH 184/701] Show only while in use subtitle for location permissions. Change-Id: I35139f9e7b7a6d5d53d4dc8b11103ebc9435c4b8 Fixes: 120629996 Test: See subtitle change correctly as I toggle permissions. --- .../ui/handheld/AppPermissionsFragment.java | 6 ++++++ .../ui/handheld/PermissionAppsFragment.java | 19 +++++++++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java index 112cdee4a..303f0cb5e 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java @@ -229,6 +229,12 @@ public final class AppPermissionsFragment extends SettingsWithHeader { preference.setSummary( context.getString(R.string.app_permission_most_recent_summary, timeDiffStr)); + } else if (group.hasPermissionWithBackgroundMode() + && group.areRuntimePermissionsGranted()) { + AppPermissionGroup backgroundGroup = group.getBackgroundPermissions(); + if (backgroundGroup == null || !backgroundGroup.areRuntimePermissionsGranted()) { + preference.setSummary(R.string.permission_access_only_foreground); + } } if (isPlatform) { diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java index 179d5593a..d7e1e97de 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java @@ -34,6 +34,7 @@ import androidx.preference.PreferenceScreen; import androidx.preference.SwitchPreferenceCompat; import com.android.packageinstaller.DeviceUtils; +import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.model.PermissionApps; import com.android.packageinstaller.permission.model.PermissionApps.Callback; import com.android.packageinstaller.permission.model.PermissionApps.PermissionApp; @@ -225,8 +226,9 @@ public final class PermissionAppsFragment extends PermissionsFrameFragment imple for (int i = 0; i < sortedApps.size(); i++) { PermissionApp app = sortedApps.get(i); + AppPermissionGroup group = app.getPermissionGroup(); - if (!Utils.shouldShowPermission(getContext(), app.getPermissionGroup())) { + if (!Utils.shouldShowPermission(getContext(), group)) { continue; } @@ -256,14 +258,16 @@ public final class PermissionAppsFragment extends PermissionsFrameFragment imple PreferenceCategory category = app.areRuntimePermissionsGranted() ? allowed : denied; if (existingPref != null) { + setSummary(existingPref, group); category.addPreference(existingPref); continue; } - Preference pref = new PermissionUsagePreference(context, app.getPermissionGroup()); + Preference pref = new PermissionUsagePreference(context, group); pref.setKey(key); pref.setIcon(app.getIcon()); pref.setTitle(app.getLabel()); + setSummary(pref, group); if (isSystemApp && isTelevision) { if (mExtraScreen == null) { @@ -316,6 +320,17 @@ public final class PermissionAppsFragment extends PermissionsFrameFragment imple } } + private void setSummary(Preference pref, AppPermissionGroup group) { + if (group.hasPermissionWithBackgroundMode() && group.areRuntimePermissionsGranted()) { + AppPermissionGroup backgroundGroup = group.getBackgroundPermissions(); + if (backgroundGroup == null || !backgroundGroup.areRuntimePermissionsGranted()) { + pref.setSummary(R.string.permission_access_only_foreground); + return; + } + } + pref.setSummary(""); + } + public static class SystemAppsFragment extends PermissionsFrameFragment implements Callback { PermissionAppsFragment mOuterFragment; -- GitLab From 59e99fc2ec939d682b62626908010a9292d77021 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Fri, 7 Dec 2018 10:22:07 -0800 Subject: [PATCH 185/701] Show correctly-sized app icon. Previously the app icon was a bit larger than it should be. This fixes it so that it is more in line with the permission icon. Change-Id: I2f89b07e0818b8c365b59b87667cf5507f226e55 Fixes: 120632634 Test: View screens. --- .../handheld/AppPermissionUsageFragment.java | 2 +- .../ui/handheld/AppPermissionsFragment.java | 2 +- .../ui/handheld/PermissionAppsFragment.java | 2 +- .../ui/handheld/PermissionUsageFragment.java | 2 +- .../ui/handheld/PermissionUsagePreference.java | 18 +++++++++++++----- 5 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java index d1ee3927b..f4eef6366 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java @@ -228,7 +228,7 @@ public class AppPermissionUsageFragment extends SettingsWithHeader { + historyEntry.getBackgroundAccessDuration(); } - Preference pref = new PermissionUsagePreference(context, group); + Preference pref = new PermissionUsagePreference(context, group, null, false); pref.setTitle(usage.getPermissionGroupLabel()); long timeDiff = System.currentTimeMillis() - usage.getTime(); if (totalDuration == 0) { diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java index 303f0cb5e..0f621c711 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java @@ -216,7 +216,7 @@ public final class AppPermissionsFragment extends SettingsWithHeader { boolean isPlatform = group.getDeclaringPackage().equals(Utils.OS_PKG); - Preference preference = new PermissionUsagePreference(context, group); + Preference preference = new PermissionUsagePreference(context, group, null, false); preference.setKey(group.getName()); Drawable icon = Utils.loadDrawable(context.getPackageManager(), group.getIconPkg(), group.getIconResId()); diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java index d7e1e97de..14b549197 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java @@ -263,7 +263,7 @@ public final class PermissionAppsFragment extends PermissionsFrameFragment imple continue; } - Preference pref = new PermissionUsagePreference(context, group); + Preference pref = new PermissionUsagePreference(context, group, null, true); pref.setKey(key); pref.setIcon(app.getIcon()); pref.setTitle(app.getLabel()); diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java index 3ce225d8b..3640e2c9e 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java @@ -349,7 +349,7 @@ public class PermissionUsageFragment extends PermissionsFrameFragment implements PermissionApp permApp = usageToApp.get(usage); Preference pref = new PermissionUsagePreference(context, group, Utils.applyTint(context, group.getIconResId(), - android.R.attr.colorControlNormal)); + android.R.attr.colorControlNormal), true); pref.setTitle(permApp.getLabel()); long timeDiff = System.currentTimeMillis() - usage.getTime(); String timeDiffStr = Utils.getTimeDiffStr(context, timeDiff); diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsagePreference.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsagePreference.java index c2701f916..4795a80fb 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsagePreference.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsagePreference.java @@ -37,12 +37,16 @@ import com.android.permissioncontroller.R; public class PermissionUsagePreference extends Preference { private final @NonNull AppPermissionGroup mGroup; private final @Nullable Drawable mWidgetIcon; + private final @NonNull Context mContext; + private final boolean mUseSmallerIcon; public PermissionUsagePreference(@NonNull Context context, @NonNull AppPermissionGroup group, - @Nullable Drawable widgetIcon) { + @Nullable Drawable widgetIcon, boolean useSmallerIcon) { super(context); mGroup = group; mWidgetIcon = widgetIcon; + mContext = context; + mUseSmallerIcon = useSmallerIcon; if (mWidgetIcon != null) { setWidgetLayoutResource(R.layout.image_view); } @@ -56,12 +60,16 @@ public class PermissionUsagePreference extends Preference { }); } - public PermissionUsagePreference(@NonNull Context context, @NonNull AppPermissionGroup group) { - this(context, group, null); - } - @Override public void onBindViewHolder(PreferenceViewHolder holder) { + if (mUseSmallerIcon) { + ImageView icon = ((ImageView) holder.findViewById(android.R.id.icon)); + icon.setMaxWidth( + mContext.getResources().getDimensionPixelSize(R.dimen.secondary_app_icon_size)); + icon.setMaxHeight( + mContext.getResources().getDimensionPixelSize(R.dimen.secondary_app_icon_size)); + } + super.onBindViewHolder(holder); if (mWidgetIcon != null) { View widgetFrame = holder.findViewById(android.R.id.widget_frame); -- GitLab From 6ee518f5dce2f8901977c0204c101a38c4c2ed56 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Fri, 7 Dec 2018 11:23:43 -0800 Subject: [PATCH 186/701] Avoid abbreviating package names unnecessarily. This ensures package names fill up the full width. Change-Id: I87711d7460b39f10e918fc968517291347fdf843 Fixes: 120661355 Test: See package names ellipsized at the end. --- .../ui/handheld/PermissionAppsFragment.java | 8 ++++++-- .../handheld/PermissionUsagePreference.java | 20 +++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java index 14b549197..e3acabcc5 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java @@ -20,6 +20,7 @@ import android.content.Context; import android.content.Intent; import android.graphics.drawable.Drawable; import android.os.Bundle; +import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; import android.view.Menu; @@ -263,10 +264,13 @@ public final class PermissionAppsFragment extends PermissionsFrameFragment imple continue; } - Preference pref = new PermissionUsagePreference(context, group, null, true); + PermissionUsagePreference pref = new PermissionUsagePreference(context, group, null, + true); pref.setKey(key); pref.setIcon(app.getIcon()); - pref.setTitle(app.getLabel()); + pref.setTitle(app.getAppInfo().loadSafeLabel(context.getPackageManager(), 0, + TextUtils.SAFE_STRING_FLAG_TRIM | TextUtils.SAFE_STRING_FLAG_FIRST_LINE)); + pref.setEllipsizeEnd(); setSummary(pref, group); if (isSystemApp && isTelevision) { diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsagePreference.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsagePreference.java index 4795a80fb..1f36b7cd6 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsagePreference.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsagePreference.java @@ -19,8 +19,10 @@ package com.android.packageinstaller.permission.ui.handheld; import android.content.Context; import android.content.Intent; import android.graphics.drawable.Drawable; +import android.text.TextUtils; import android.view.View; import android.widget.ImageView; +import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -39,6 +41,7 @@ public class PermissionUsagePreference extends Preference { private final @Nullable Drawable mWidgetIcon; private final @NonNull Context mContext; private final boolean mUseSmallerIcon; + private boolean mEllipsizeEnd; public PermissionUsagePreference(@NonNull Context context, @NonNull AppPermissionGroup group, @Nullable Drawable widgetIcon, boolean useSmallerIcon) { @@ -47,6 +50,7 @@ public class PermissionUsagePreference extends Preference { mWidgetIcon = widgetIcon; mContext = context; mUseSmallerIcon = useSmallerIcon; + mEllipsizeEnd = false; if (mWidgetIcon != null) { setWidgetLayoutResource(R.layout.image_view); } @@ -60,6 +64,15 @@ public class PermissionUsagePreference extends Preference { }); } + /** + * Sets this preference's title to use an ellipsis at the end. + * + * Note that this must be called before preference layout to take effect. + */ + public void setEllipsizeEnd() { + mEllipsizeEnd = true; + } + @Override public void onBindViewHolder(PreferenceViewHolder holder) { if (mUseSmallerIcon) { @@ -71,9 +84,16 @@ public class PermissionUsagePreference extends Preference { } super.onBindViewHolder(holder); + if (mWidgetIcon != null) { View widgetFrame = holder.findViewById(android.R.id.widget_frame); ((ImageView) widgetFrame.findViewById(R.id.icon)).setImageDrawable(mWidgetIcon); } + + if (mEllipsizeEnd) { + TextView title = (TextView) holder.findViewById(android.R.id.title); + title.setMaxLines(1); + title.setEllipsize(TextUtils.TruncateAt.END); + } } } -- GitLab From dcd7ff48c6de4bd56d97445fe6821831da7c889e Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Mon, 10 Dec 2018 10:31:21 -0800 Subject: [PATCH 187/701] Show message when no apps/permissions are allowed/denied. Instead of showing an empty allowed/denied header, we now show a message saying that nothing is there. Change-Id: I6e8ccd31c4af9f9ef6a0f699bc91fd7fd732e52b Fixes: 120675937 Test: See messages when no apps/permissions are allowed/denied. Test: Ensure message appears/disappears as I toggle permissions. --- res/values/strings.xml | 12 ++++++++++++ .../ui/handheld/AppPermissionsFragment.java | 11 +++++++++++ .../ui/handheld/PermissionAppsFragment.java | 11 +++++++++++ 3 files changed, 34 insertions(+) diff --git a/res/values/strings.xml b/res/values/strings.xml index 1968cf6a0..6adbfeaed 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -395,6 +395,18 @@ The app developer did not specify how the app uses your data. + + No permissions allowed + + + No permissions denied + + + No apps allowed + + + No apps denied + Default apps diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java index 0f621c711..468fbcfe7 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java @@ -270,6 +270,17 @@ public final class AppPermissionsFragment extends SettingsWithHeader { category.addPreference(extraPerms); } + if (allowed.getPreferenceCount() == 0) { + Preference empty = new Preference(context); + empty.setTitle(getString(R.string.no_permissions_allowed)); + allowed.addPreference(empty); + } + if (denied.getPreferenceCount() == 0) { + Preference empty = new Preference(context); + empty.setTitle(getString(R.string.no_permissions_denied)); + denied.addPreference(empty); + } + setLoading(false /* loading */, true /* animate */); } diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java index e3acabcc5..2d5a50fe9 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java @@ -317,6 +317,17 @@ public final class PermissionAppsFragment extends PermissionsFrameFragment imple grantedCount, mExtraScreen.getPreferenceCount())); } + if (allowed.getPreferenceCount() == 0) { + Preference empty = new Preference(context); + empty.setTitle(getString(R.string.no_apps_allowed)); + allowed.addPreference(empty); + } + if (denied.getPreferenceCount() == 0) { + Preference empty = new Preference(context); + empty.setTitle(getString(R.string.no_apps_denied)); + denied.addPreference(empty); + } + setLoading(false /* loading */, true /* animate */); if (mOnPermissionsLoadedListener != null) { -- GitLab From 7e1956dc28f31f60b2cc566f4574de09dd4004b5 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Mon, 10 Dec 2018 12:44:25 -0800 Subject: [PATCH 188/701] Clean up and rename PermissionUsagePreference. Clean up PermissionUsagePreference by adding some utility methods. I also renamed it since it hasn't had a usage object in a while. Test: Open various Fragments and see everything as expected. Change-Id: Ic1b3effd7cfda6f5afa9eb82758d87f3202530bd --- .../handheld/AppPermissionUsageFragment.java | 2 +- .../ui/handheld/AppPermissionsFragment.java | 11 ++-- .../ui/handheld/PermissionAppsFragment.java | 21 ++----- ....java => PermissionControlPreference.java} | 61 +++++++++++++++---- .../ui/handheld/PermissionUsageFragment.java | 8 +-- 5 files changed, 63 insertions(+), 40 deletions(-) rename src/com/android/packageinstaller/permission/ui/handheld/{PermissionUsagePreference.java => PermissionControlPreference.java} (61%) diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java index f4eef6366..0e0b3e9d9 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java @@ -228,7 +228,7 @@ public class AppPermissionUsageFragment extends SettingsWithHeader { + historyEntry.getBackgroundAccessDuration(); } - Preference pref = new PermissionUsagePreference(context, group, null, false); + Preference pref = new PermissionControlPreference(context, group); pref.setTitle(usage.getPermissionGroupLabel()); long timeDiff = System.currentTimeMillis() - usage.getTime(); if (totalDuration == 0) { diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java index 468fbcfe7..dcb4132bc 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java @@ -216,7 +216,8 @@ public final class AppPermissionsFragment extends SettingsWithHeader { boolean isPlatform = group.getDeclaringPackage().equals(Utils.OS_PKG); - Preference preference = new PermissionUsagePreference(context, group, null, false); + PermissionControlPreference preference = new PermissionControlPreference(context, + group); preference.setKey(group.getName()); Drawable icon = Utils.loadDrawable(context.getPackageManager(), group.getIconPkg(), group.getIconResId()); @@ -229,12 +230,8 @@ public final class AppPermissionsFragment extends SettingsWithHeader { preference.setSummary( context.getString(R.string.app_permission_most_recent_summary, timeDiffStr)); - } else if (group.hasPermissionWithBackgroundMode() - && group.areRuntimePermissionsGranted()) { - AppPermissionGroup backgroundGroup = group.getBackgroundPermissions(); - if (backgroundGroup == null || !backgroundGroup.areRuntimePermissionsGranted()) { - preference.setSummary(R.string.permission_access_only_foreground); - } + } else { + preference.setGroupSummary(group); } if (isPlatform) { diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java index 2d5a50fe9..1f8ea2811 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java @@ -259,19 +259,21 @@ public final class PermissionAppsFragment extends PermissionsFrameFragment imple PreferenceCategory category = app.areRuntimePermissionsGranted() ? allowed : denied; if (existingPref != null) { - setSummary(existingPref, group); + if (existingPref instanceof PermissionControlPreference) { + ((PermissionControlPreference) existingPref).setGroupSummary(group); + } category.addPreference(existingPref); continue; } - PermissionUsagePreference pref = new PermissionUsagePreference(context, group, null, - true); + PermissionControlPreference pref = new PermissionControlPreference(context, group); pref.setKey(key); pref.setIcon(app.getIcon()); pref.setTitle(app.getAppInfo().loadSafeLabel(context.getPackageManager(), 0, TextUtils.SAFE_STRING_FLAG_TRIM | TextUtils.SAFE_STRING_FLAG_FIRST_LINE)); pref.setEllipsizeEnd(); - setSummary(pref, group); + pref.useSmallerIcon(); + pref.setGroupSummary(group); if (isSystemApp && isTelevision) { if (mExtraScreen == null) { @@ -335,17 +337,6 @@ public final class PermissionAppsFragment extends PermissionsFrameFragment imple } } - private void setSummary(Preference pref, AppPermissionGroup group) { - if (group.hasPermissionWithBackgroundMode() && group.areRuntimePermissionsGranted()) { - AppPermissionGroup backgroundGroup = group.getBackgroundPermissions(); - if (backgroundGroup == null || !backgroundGroup.areRuntimePermissionsGranted()) { - pref.setSummary(R.string.permission_access_only_foreground); - return; - } - } - pref.setSummary(""); - } - public static class SystemAppsFragment extends PermissionsFrameFragment implements Callback { PermissionAppsFragment mOuterFragment; diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsagePreference.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionControlPreference.java similarity index 61% rename from src/com/android/packageinstaller/permission/ui/handheld/PermissionUsagePreference.java rename to src/com/android/packageinstaller/permission/ui/handheld/PermissionControlPreference.java index 1f36b7cd6..e0d8891f8 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsagePreference.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionControlPreference.java @@ -34,36 +34,55 @@ import com.android.packageinstaller.permission.ui.AppPermissionActivity; import com.android.permissioncontroller.R; /** - * A preference for representing a permission usage by an app. + * A preference that links to the screen where a permission can be toggled. */ -public class PermissionUsagePreference extends Preference { - private final @NonNull AppPermissionGroup mGroup; - private final @Nullable Drawable mWidgetIcon; +public class PermissionControlPreference extends Preference { private final @NonNull Context mContext; - private final boolean mUseSmallerIcon; + private @Nullable Drawable mWidgetIcon; + private boolean mUseSmallerIcon; private boolean mEllipsizeEnd; - public PermissionUsagePreference(@NonNull Context context, @NonNull AppPermissionGroup group, - @Nullable Drawable widgetIcon, boolean useSmallerIcon) { + public PermissionControlPreference(@NonNull Context context, + @NonNull AppPermissionGroup group) { super(context); - mGroup = group; - mWidgetIcon = widgetIcon; mContext = context; - mUseSmallerIcon = useSmallerIcon; + mWidgetIcon = null; + mUseSmallerIcon = false; mEllipsizeEnd = false; if (mWidgetIcon != null) { setWidgetLayoutResource(R.layout.image_view); } setOnPreferenceClickListener(preference -> { Intent intent = new Intent(context, AppPermissionActivity.class); - intent.putExtra(Intent.EXTRA_PACKAGE_NAME, mGroup.getApp().packageName); - intent.putExtra(Intent.EXTRA_PERMISSION_NAME, mGroup.getName()); - intent.putExtra(Intent.EXTRA_USER, mGroup.getUser()); + intent.putExtra(Intent.EXTRA_PACKAGE_NAME, group.getApp().packageName); + intent.putExtra(Intent.EXTRA_PERMISSION_NAME, group.getName()); + intent.putExtra(Intent.EXTRA_USER, group.getUser()); context.startActivity(intent); return true; }); } + /** + * Sets this preference's right icon. + * + * Note that this must be called before preference layout to take effect. + * + * @param widgetIcon the icon to use. + */ + public void setRightIcon(@NonNull Drawable widgetIcon) { + mWidgetIcon = widgetIcon; + setWidgetLayoutResource(R.layout.image_view); + } + + /** + * Sets this preference's left icon to be smaller than normal. + * + * Note that this must be called before preference layout to take effect. + */ + public void useSmallerIcon() { + mUseSmallerIcon = true; + } + /** * Sets this preference's title to use an ellipsis at the end. * @@ -73,6 +92,22 @@ public class PermissionUsagePreference extends Preference { mEllipsizeEnd = true; } + /** + * Sets this preference's summary based on the group it represents, if applicable. + * + * @param group the permission group this preference represents. + */ + public void setGroupSummary(@NonNull AppPermissionGroup group) { + if (group.hasPermissionWithBackgroundMode() && group.areRuntimePermissionsGranted()) { + AppPermissionGroup backgroundGroup = group.getBackgroundPermissions(); + if (backgroundGroup == null || !backgroundGroup.areRuntimePermissionsGranted()) { + setSummary(R.string.permission_access_only_foreground); + return; + } + } + setSummary(""); + } + @Override public void onBindViewHolder(PreferenceViewHolder holder) { if (mUseSmallerIcon) { diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java index 3640e2c9e..47c2f12d9 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java @@ -35,7 +35,6 @@ import android.widget.Spinner; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.preference.Preference; import androidx.preference.PreferenceScreen; import com.android.packageinstaller.permission.model.AppPermissionGroup; @@ -347,16 +346,17 @@ public class PermissionUsageFragment extends PermissionsFrameFragment implements } AppPermissionGroup group = usageToGroup.get(usage); PermissionApp permApp = usageToApp.get(usage); - Preference pref = new PermissionUsagePreference(context, group, - Utils.applyTint(context, group.getIconResId(), - android.R.attr.colorControlNormal), true); + PermissionControlPreference pref = new PermissionControlPreference(context, group); pref.setTitle(permApp.getLabel()); long timeDiff = System.currentTimeMillis() - usage.getTime(); String timeDiffStr = Utils.getTimeDiffStr(context, timeDiff); pref.setSummary(context.getString(R.string.permission_usage_summary, usage.getPermissionGroupLabel(), timeDiffStr)); pref.setIcon(permApp.getIcon()); + pref.setRightIcon(Utils.applyTint(context, group.getIconResId(), + android.R.attr.colorControlNormal)); pref.setKey(usage.getPackageName() + "," + usage.getPermissionGroupName()); + pref.useSmallerIcon(); screen.addPreference(pref); } } -- GitLab From e85772134c0b90db97cd63fa1010bb6cbc85bad8 Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Mon, 10 Dec 2018 12:47:36 -0800 Subject: [PATCH 189/701] Allow meta data requirement of a role to be optional. This change allows a meta data requirement of a role to be optional. This can be used in cases such as when a meta data must have the value of false or be undeclared to qualify for a role. Bug: 110557011 Test: manual Change-Id: I1d6c7c94159be573659422119fbb618adeddb7af --- .../role/model/RequiredActivity.java | 3 +- .../role/model/RequiredBroadcastReceiver.java | 3 +- .../role/model/RequiredComponent.java | 28 ++--- .../role/model/RequiredContentProvider.java | 3 +- .../role/model/RequiredMetaData.java | 113 ++++++++++++++++++ .../role/model/RequiredService.java | 3 +- .../packageinstaller/role/model/Roles.java | 20 +++- 7 files changed, 148 insertions(+), 25 deletions(-) create mode 100644 src/com/android/packageinstaller/role/model/RequiredMetaData.java diff --git a/src/com/android/packageinstaller/role/model/RequiredActivity.java b/src/com/android/packageinstaller/role/model/RequiredActivity.java index 85403ac20..b39bbd1d5 100644 --- a/src/com/android/packageinstaller/role/model/RequiredActivity.java +++ b/src/com/android/packageinstaller/role/model/RequiredActivity.java @@ -22,7 +22,6 @@ import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.Bundle; -import android.util.ArrayMap; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -35,7 +34,7 @@ import java.util.List; public class RequiredActivity extends RequiredComponent { public RequiredActivity(@NonNull IntentFilterData intentFilterData, - @Nullable String permission, @NonNull ArrayMap metaData) { + @Nullable String permission, @NonNull List metaData) { super(intentFilterData, permission, metaData); } diff --git a/src/com/android/packageinstaller/role/model/RequiredBroadcastReceiver.java b/src/com/android/packageinstaller/role/model/RequiredBroadcastReceiver.java index 101119d2f..21eb670af 100644 --- a/src/com/android/packageinstaller/role/model/RequiredBroadcastReceiver.java +++ b/src/com/android/packageinstaller/role/model/RequiredBroadcastReceiver.java @@ -22,7 +22,6 @@ import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.Bundle; -import android.util.ArrayMap; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -35,7 +34,7 @@ import java.util.List; public class RequiredBroadcastReceiver extends RequiredComponent { public RequiredBroadcastReceiver(@NonNull IntentFilterData intentFilterData, - @Nullable String permission, @NonNull ArrayMap metaData) { + @Nullable String permission, @NonNull List metaData) { super(intentFilterData, permission, metaData); } diff --git a/src/com/android/packageinstaller/role/model/RequiredComponent.java b/src/com/android/packageinstaller/role/model/RequiredComponent.java index 207857bc0..e810af696 100644 --- a/src/com/android/packageinstaller/role/model/RequiredComponent.java +++ b/src/com/android/packageinstaller/role/model/RequiredComponent.java @@ -22,8 +22,8 @@ import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.Bundle; -import android.util.ArrayMap; import android.util.ArraySet; +import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -37,6 +37,8 @@ import java.util.Objects; */ public abstract class RequiredComponent { + private static final String LOG_TAG = RequiredComponent.class.getSimpleName(); + /** * The {@code Intent} or {@code IntentFilter} data to match the components. */ @@ -58,10 +60,11 @@ public abstract class RequiredComponent { * @see android.content.pm.PackageItemInfo#metaData */ @NonNull - private final ArrayMap mMetaData; + private final List mMetaData; public RequiredComponent(@NonNull IntentFilterData intentFilterData, - @Nullable String permission, @NonNull ArrayMap metaData) { + @Nullable String permission, + @NonNull List metaData) { mIntentFilterData = intentFilterData; mPermission = permission; mMetaData = metaData; @@ -78,7 +81,7 @@ public abstract class RequiredComponent { } @NonNull - public ArrayMap getMetaData() { + public List getMetaData() { return mMetaData; } @@ -144,23 +147,20 @@ public abstract class RequiredComponent { if (hasMetaData) { Bundle componentMetaData = getComponentMetaData(resolveInfo); if (componentMetaData == null) { + Log.w(LOG_TAG, "Component meta data is null"); continue; } + boolean isMetaDataQualified = true; int metaDataSize = mMetaData.size(); - if (componentMetaData.size() < metaDataSize) { - continue; - } - boolean containsAllMetaData = true; for (int metaDataIndex = 0; metaDataIndex < metaDataSize; metaDataIndex++) { - String metaDataName = mMetaData.keyAt(metaDataIndex); - Object metaDataValue = mMetaData.valueAt(metaDataIndex); - Object componentMetaDataValue = componentMetaData.get(metaDataName); - if (!Objects.equals(componentMetaDataValue, metaDataValue)) { - containsAllMetaData = false; + RequiredMetaData metaData = mMetaData.get(metaDataIndex); + + if (!metaData.isQualified(componentMetaData)) { + isMetaDataQualified = false; break; } } - if (!containsAllMetaData) { + if (!isMetaDataQualified) { continue; } } diff --git a/src/com/android/packageinstaller/role/model/RequiredContentProvider.java b/src/com/android/packageinstaller/role/model/RequiredContentProvider.java index dc781beab..eb0f5f079 100644 --- a/src/com/android/packageinstaller/role/model/RequiredContentProvider.java +++ b/src/com/android/packageinstaller/role/model/RequiredContentProvider.java @@ -22,7 +22,6 @@ import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.Bundle; -import android.util.ArrayMap; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -35,7 +34,7 @@ import java.util.List; public class RequiredContentProvider extends RequiredComponent { public RequiredContentProvider(@NonNull IntentFilterData intentFilterData, - @Nullable String permission, @NonNull ArrayMap metaData) { + @Nullable String permission, @NonNull List metaData) { super(intentFilterData, permission, metaData); } diff --git a/src/com/android/packageinstaller/role/model/RequiredMetaData.java b/src/com/android/packageinstaller/role/model/RequiredMetaData.java new file mode 100644 index 000000000..5b97e0b1e --- /dev/null +++ b/src/com/android/packageinstaller/role/model/RequiredMetaData.java @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.packageinstaller.role.model; + +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import java.util.Objects; + +/** + * Specifies the value of a meta data for an application to qualify for a {@link Role}. + */ +public class RequiredMetaData { + + /** + * The name of this meta data. + */ + @NonNull + private final String mName; + + /** + * The value of this meta data. + */ + @Nullable + private final Object mValue; + + /** + * Whether this meta data is optional. + * + * @see #isQualified(Bundle) + */ + private final boolean mOptional; + + public RequiredMetaData(@NonNull String name, @Nullable Object value, boolean optional) { + mName = name; + mValue = value; + mOptional = optional; + } + + @NonNull + public String getName() { + return mName; + } + + @Nullable + public Object getValue() { + return mValue; + } + + public boolean isOptional() { + return mOptional; + } + + /** + * Check whether the meta data of a component is qualified. + * + * @param metaData the meta data of the component + * + * @return whether the meta data of the component is qualified + */ + public boolean isQualified(@NonNull Bundle metaData) { + if (metaData.containsKey(mName)) { + Object metaDataValue = metaData.get(mName); + return Objects.equals(metaDataValue, mValue); + } else { + return mOptional; + } + } + + @Override + public String toString() { + return "RequiredMetaData{" + + "mName='" + mName + '\'' + + ", mValue=" + mValue + + ", mOptional=" + mOptional + + '}'; + } + + @Override + public boolean equals(Object object) { + if (this == object) { + return true; + } + if (object == null || getClass() != object.getClass()) { + return false; + } + RequiredMetaData that = (RequiredMetaData) object; + return mOptional == that.mOptional + && Objects.equals(mName, that.mName) + && Objects.equals(mValue, that.mValue); + } + + @Override + public int hashCode() { + return Objects.hash(mName, mValue, mOptional); + } +} diff --git a/src/com/android/packageinstaller/role/model/RequiredService.java b/src/com/android/packageinstaller/role/model/RequiredService.java index d0d90e50f..9bab7b9f7 100644 --- a/src/com/android/packageinstaller/role/model/RequiredService.java +++ b/src/com/android/packageinstaller/role/model/RequiredService.java @@ -22,7 +22,6 @@ import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.Bundle; -import android.util.ArrayMap; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -35,7 +34,7 @@ import java.util.List; public class RequiredService extends RequiredComponent { public RequiredService(@NonNull IntentFilterData intentFilterData, - @Nullable String permission, @NonNull ArrayMap metaData) { + @Nullable String permission, @NonNull List metaData) { super(intentFilterData, permission, metaData); } diff --git a/src/com/android/packageinstaller/role/model/Roles.java b/src/com/android/packageinstaller/role/model/Roles.java index bfeb4b5b7..8d8afce67 100644 --- a/src/com/android/packageinstaller/role/model/Roles.java +++ b/src/com/android/packageinstaller/role/model/Roles.java @@ -76,6 +76,7 @@ public class Roles { private static final String ATTRIBUTE_SCHEME = "scheme"; private static final String ATTRIBUTE_MIME_TYPE = "mimeType"; private static final String ATTRIBUTE_VALUE = "value"; + private static final String ATTRIBUTE_OPTIONAL = "optional"; private static final String ATTRIBUTE_MODE = "mode"; private static final String MODE_NAME_ALLOWED = "allowed"; @@ -410,7 +411,11 @@ public class Roles { @NonNull String name) throws IOException, XmlPullParserException { String permission = getAttributeValue(parser, ATTRIBUTE_PERMISSION); IntentFilterData intentFilterData = null; - ArrayMap metaData = new ArrayMap<>(); + List metaData = new ArrayList<>(); + List metaDataNames; + if (DEBUG) { + metaDataNames = new ArrayList<>(); + } int type; int depth; @@ -437,7 +442,9 @@ public class Roles { if (metaDataName == null) { continue; } - checkDuplicateElement(metaDataName, metaData.keySet(), "meta data"); + if (DEBUG) { + checkDuplicateElement(metaDataName, metaDataNames, "meta data"); + } // HACK: Only support boolean for now. // TODO: Support android:resource and other types of android:value, maybe by // switching to TypedArray and styleables. @@ -446,7 +453,14 @@ public class Roles { if (metaDataValue == null) { continue; } - metaData.put(metaDataName, metaDataValue); + boolean metaDataOptional = getAttributeBooleanValue(parser, ATTRIBUTE_OPTIONAL, + false); + RequiredMetaData requiredMetaData = new RequiredMetaData(metaDataName, + metaDataValue, metaDataOptional); + metaData.add(requiredMetaData); + if (DEBUG) { + metaDataNames.add(metaDataName); + } break; default: throwOrLogForUnknownTag(parser); -- GitLab From 454c2fb3b0bdd691132bd362b1583f79fd4593cc Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Tue, 11 Dec 2018 05:24:16 -0800 Subject: [PATCH 190/701] Import translations. DO NOT MERGE Change-Id: I1e1920a8356eab48f2bfc37fef87146548eb00e9 Auto-generated-cl: translation import --- res/values-af/strings.xml | 64 +++++++++---------- res/values-am/strings.xml | 64 +++++++++---------- res/values-ar/strings.xml | 68 ++++++++++----------- res/values-as/strings.xml | 67 ++++++++++---------- res/values-az/strings.xml | 64 +++++++++---------- res/values-b+sr+Latn/strings.xml | 65 ++++++++++---------- res/values-be/strings.xml | 66 ++++++++++---------- res/values-bg/strings.xml | 64 +++++++++---------- res/values-bn/strings.xml | 64 +++++++++---------- res/values-bs/strings.xml | 65 ++++++++++---------- res/values-ca/strings.xml | 64 +++++++++---------- res/values-cs/strings.xml | 66 ++++++++++---------- res/values-da/strings.xml | 64 +++++++++---------- res/values-de/strings.xml | 64 +++++++++---------- res/values-el/strings.xml | 64 +++++++++---------- res/values-en-rAU/strings.xml | 64 +++++++++---------- res/values-en-rCA/strings.xml | 64 +++++++++---------- res/values-en-rGB/strings.xml | 64 +++++++++---------- res/values-en-rIN/strings.xml | 64 +++++++++---------- res/values-en-rXC/strings.xml | 26 +++++--- res/values-es-rUS/strings.xml | 64 +++++++++---------- res/values-es/strings.xml | 64 +++++++++---------- res/values-et/strings.xml | 64 +++++++++---------- res/values-eu/strings.xml | 26 +++++--- res/values-fa/strings.xml | 64 +++++++++---------- res/values-fi/strings.xml | 64 +++++++++---------- res/values-fr-rCA/strings.xml | 64 +++++++++---------- res/values-fr/strings.xml | 64 +++++++++---------- res/values-gl/strings.xml | 64 +++++++++---------- res/values-gu/strings.xml | 67 ++++++++++---------- res/values-hi/strings.xml | 64 +++++++++---------- res/values-hr/strings.xml | 65 ++++++++++---------- res/values-hu/strings.xml | 64 +++++++++---------- res/values-hy/strings.xml | 64 +++++++++---------- res/values-in/strings.xml | 64 +++++++++---------- res/values-is/strings.xml | 64 +++++++++---------- res/values-it/strings.xml | 64 +++++++++---------- res/values-iw/strings.xml | 66 ++++++++++---------- res/values-ja/strings.xml | 64 +++++++++---------- res/values-ka/strings.xml | 64 +++++++++---------- res/values-kk/strings.xml | 64 +++++++++---------- res/values-km/strings.xml | 64 +++++++++---------- res/values-kn/strings.xml | 67 ++++++++++---------- res/values-ko/strings.xml | 64 +++++++++---------- res/values-ky/strings.xml | 64 +++++++++---------- res/values-lo/strings.xml | 64 +++++++++---------- res/values-lt/strings.xml | 66 ++++++++++---------- res/values-lv/strings.xml | 65 ++++++++++---------- res/values-mk/strings.xml | 64 +++++++++---------- res/values-ml/strings.xml | 67 ++++++++++---------- res/values-mn/strings.xml | 64 +++++++++---------- res/values-mr-television/strings.xml | 4 +- res/values-mr/strings.xml | 91 ++++++++++++++-------------- res/values-ms/strings.xml | 64 +++++++++---------- res/values-my/strings.xml | 64 +++++++++---------- res/values-nb/strings.xml | 64 +++++++++---------- res/values-ne/strings.xml | 64 +++++++++---------- res/values-nl/strings.xml | 64 +++++++++---------- res/values-or/strings.xml | 64 +++++++++---------- res/values-pa/strings.xml | 67 ++++++++++---------- res/values-pl/strings.xml | 66 ++++++++++---------- res/values-pt-rBR/strings.xml | 64 +++++++++---------- res/values-pt-rPT/strings.xml | 26 +++++--- res/values-pt/strings.xml | 64 +++++++++---------- res/values-ro/strings.xml | 65 ++++++++++---------- res/values-ru/strings.xml | 66 ++++++++++---------- res/values-si/strings.xml | 64 +++++++++---------- res/values-sk/strings.xml | 66 ++++++++++---------- res/values-sl/strings.xml | 66 ++++++++++---------- res/values-sq/strings.xml | 64 +++++++++---------- res/values-sr/strings.xml | 65 ++++++++++---------- res/values-sv/strings.xml | 64 +++++++++---------- res/values-sw/strings.xml | 64 +++++++++---------- res/values-ta/strings.xml | 64 +++++++++---------- res/values-te/strings.xml | 67 ++++++++++---------- res/values-th/strings.xml | 64 +++++++++---------- res/values-tl/strings.xml | 64 +++++++++---------- res/values-tr/strings.xml | 64 +++++++++---------- res/values-uk/strings.xml | 66 ++++++++++---------- res/values-ur/strings.xml | 67 ++++++++++---------- res/values-uz/strings.xml | 64 +++++++++---------- res/values-vi/strings.xml | 64 +++++++++---------- res/values-zh-rCN/strings.xml | 64 +++++++++---------- res/values-zh-rHK/strings.xml | 64 +++++++++---------- res/values-zh-rTW/strings.xml | 64 +++++++++---------- res/values-zu/strings.xml | 64 +++++++++---------- 86 files changed, 2580 insertions(+), 2826 deletions(-) diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml index 8bd6a34f0..78084a164 100644 --- a/res/values-af/strings.xml +++ b/res/values-af/strings.xml @@ -95,7 +95,8 @@ "Afgelope 15 minute" "Geen toestemminggebruike nie" "Programtoestemmingsgebruik" - "%1$s gelede" + "Toegang: %1$s keer. Totale tydsduur: %2$s. %3$s gelede laas gebruik." + "Toegang: %1$s keer. %2$s gelede laas gebruik." "Laat toe" "Laat altyd toe" "Laat net toe terwyl die program gebruik word" @@ -103,15 +104,11 @@ "%1$s-toestemming" "%1$s-toegang vir %2$s" "%1$s het %3$s gelede toegang tot jou %2$s verkry." - - + "%1$s het nie toegang gekry tot jou %2$s nie." "Bekyk gedetailleerde toestemmingsgebruik" - - - - - - + "Mees onlangse toegang was %1$s gelede" + "Toegelaat" + "Geweier" %s dae 1 dag @@ -136,36 +133,35 @@ - + "Die programontwikkelaar sê jou data kan:" + "As jy nie hou van hoe hierdie programontwikkelaar jou data gebruik nie, kan jy die toestemming weier." + "Opgelaai word na wolk toe" + "Opgelaai word na wolk toe wanneer jy dit uitdruklik toelaat" + "Gedeel word met adverteerders of besighede" + "Gedeel word met adverteerders of besighede wanneer jy dit uitdruklik toelaat" + "Gebruik word vir monetisering" + "Gebruik word vir monetisering wanneer jy dit uitdruklik toelaat" + "Vir altyd gestoor en ontleed word" + "Gestoor en ontleed word vir \'n tydsduur wat jy spesifiseer" + + Gestoor en ontleed vir %s weke + Gestoor en ontleed vir 1 week + + "Die programontwikkelaar het nie gespesifiseer hoe die program jou data gebruik nie." + - + + + + + + "Verstekprogramme" + "Geen verstekprogramme nie" + "Geen programme nie" "Foonprogram" "SMS-program" "Blaaierprogram" "Galeryprogram" "Musiekprogram" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml index d84f7ce5b..b99b2644c 100644 --- a/res/values-am/strings.xml +++ b/res/values-am/strings.xml @@ -95,7 +95,8 @@ "ባለፉት 15 ደቂቃዎች" "ምንም ፈቃድ አጠቃቀሞች የሉም" "የመተግበሪያ ፈቃዶች አጠቃቀም" - "ከ%1$s በፊት" + "ድረስበት፦ %1$s ጊዜ። አጠቃላይ ቆይታ ጊዜ፦ %2$s። ለመጨረሻ ጥቅም ላይ የዋለው ከ%3$s በፊት።" + "ድረስበት፦ %1$s ጊዜ። ለመጨረሻ ጥቅም ላይ የዋለው ከ%2$s በፊት።" "ፍቀድ" "ሁልጊዜ ፍቀድ" "መተግበሪያው ጥቅም ላይ እያለ ብቻ ፍቀድ" @@ -103,15 +104,11 @@ "የ%1$s ፈቃድ" "ለ%2$s%1$s መዳረሻ" "%1$s%3$s በፊት የእርስዎን %2$s ደርሶ ነበር።" - - + "%1$s የእርስዎን %2$s አልደረሰበትም።" "ዝርዝር የፈቃዶች አጠቃቀምን ይመልከቱ" - - - - - - + "በጣም የቅርብ ጊዜ መድረስ %1$s በፊት" + "ይፈቀዳል" + "ውድቅ ተደርጓል" %s ቀኖች %s ቀኖች @@ -136,36 +133,35 @@ - + "የመተግበሪያው ገንቢ የእርስዎ ውሂብ እንዲህ ሊሆን ይችላል ይላል፦" + "የዚህ መተግበሪያ ገንቢ የእርስዎን ውሂብ የሚጠቀምበት ሁኔታ ደስ ካላልዎት ፈቃዱን መከልከል ይችላሉ።" + "ወደ ደመና ይሰቀላል" + "እርስዎ ሲፈቅዱ ወደ ደመና ይሰቀላል" + "ከማስታወቂያ አስነጋሪዎች ወይም ንግዶች ጋር ይጋራል" + "እርስዎ በግልፅ ሲፈቅዱ ከማስታወቂያ አስነጋሪዎች ወይም ንግዶች ጋር ይጋራል" + "ለገንዘብ ማግኛ ጥቅም ላይ ይውላል" + "እርስዎ በግልፅ ሲፈቅዱ ለገንዘብ ማስገኛ ሥራዎች ጥቅም ላይ ይውላል" + "ይቀመጥና ለዘላለም ይተነተናል" + "እርስዎ ለጠቀሱት ጊዜ ቆይታ ይቀመጣል እና ይተነተናል" + + %s ሳምንታት ይቀመጣል እና ይተነተናል + %s ሳምንታት ይቀመጣል እና ይተነተናል + + "የመተግበሪያው ገንቢ መተግበሪያው እንዴት የእርስዎን ውሂብ እንደሚጠቀም አልጠቀሰም።" + - + + + + + + "ነባሪ መተግበሪያዎች" + "ምንም ነባሪ መተግበሪያዎች የሉም" + "ምንም መተግበሪያዎች የሉም" "የስልክ መተግበሪያ" "የኤስኤምኤስ መተግበሪያ" "የአሳሽ መተግበሪያ" "የማዕከለ ሥዕላት መተግበሪያ" "የሙዚቃ መተግበሪያ" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml index 351c7fa10..c335c707a 100644 --- a/res/values-ar/strings.xml +++ b/res/values-ar/strings.xml @@ -99,7 +99,8 @@ "آخر 15 دقيقة" "لم يتمّ استخدام الأذونات" "استخدام أذونات التطبيق" - "قبل %1$s" + "استخدام الإذن: %1$s مرّة إجمالي المدّة: %2$s. آخر استخدام قبل %3$s." + "استخدام الإذن: %1$s مرّة آخر استخدام قبل %2$s." "سماح" "السماح طوال الوقت" "السماح فقط أثناء استخدام التطبيق" @@ -107,15 +108,11 @@ "إذن %1$s" "إذن %1$s الممنوح للتطبيق %2$s" "قبل %3$s، استخدَم تطبيق %1$s إذن %2$s الذي منحته." - - + "لم يحصل تطبيق %1$s على إذن %2$s." "عرض تفاصيل استخدام الأذونات" - - - - - - + "أحدث دخول إلى البيانات كان قبل %1$s." + "التطبيقات أو الأذونات المسموح بها" + "التطبيقات أو الأذونات المرفوضة" %s يوم يومان (%s) @@ -156,36 +153,39 @@ - + "يشير مطوّر التطبيق إلى احتمالية إجراء ما يلي بشأن البيانات:" + "إذا لم تعجبك طريقة استخدام مطوّر هذا التطبيق لبياناتك، يمكنك رفض الإذن." + "يتم تحميل البيانات إلى السحابة الإلكترونية." + "يتم تحميل البيانات إلى السحابة الإلكترونية عند السماح بذلك بوضوح." + "تتم مشاركة البيانات مع المعلنين أو الأنشطة التجارية." + "تتم مشاركة البيانات مع المعلنين أو الأنشطة التجارية عند السماح بذلك بوضوح." + "يتم استخدام البيانات لتحقيق الربح المادي." + "يتم استخدام الإذن لتحقيق ربح مادي عند السماح بذلك بوضوح." + "يتم تحليل البيانات وحفظها إلى الأبد." + "يتم تحليل البيانات وحفظها للمدة التي تحدّدها." + + يتم تحليل البيانات وحفظها لمدة %s أسبوع.​ + يتم تحليل البيانات وحفظها لمدة أسبوعين (%s). + يتم تحليل البيانات وحفظها لمدة %s أسابيع. + يتم تحليل البيانات وحفظها لمدة %s أسبوعًا. + يتم تحليل البيانات وحفظها لمدة %s أسبوع.​ + يتم تحليل البيانات وحفظها لمدة أسبوع واحد. + + "لم يحدّد المطوّر طريقة استخدام التطبيق للبيانات." + - + + + + + + "التطبيقات التلقائية" + "ليست هناك تطبيقات تلقائية." + "ليس هناك أيّ تطبيقات." "تطبيق الهاتف" "‏تطبيق SMS" "تطبيق المتصفّح" "تطبيق المعرض" "تطبيق الموسيقى" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml index 5f045475a..9a34e25de 100644 --- a/res/values-as/strings.xml +++ b/res/values-as/strings.xml @@ -95,7 +95,10 @@ "যোৱা ১৫ মিনিটত" "অনুমতি ব্যৱহাৰ কৰা হোৱা নাই" "এপৰ অনুমতিৰ ব্যৱহাৰ" - "%1$s আগত" + + + + "অনুমতি দিয়ক" "সকলো সময়ৰ বাবে অনুমতি দিয়ক" "কেৱল এপটো ব্যৱহাৰ হৈ থকা সময়ত অনুমতি দিয়ক" @@ -103,15 +106,11 @@ "%1$s অনুমতি" "%2$s%1$s এক্সেছ" "%1$sএ আপোনাৰ %2$s%3$s পূর্বে এক্সেছ পাইছিল।" - - + "%1$sএ আপোনাৰ %2$s এক্সেছ কৰা নাই।" "অনুমতিৰ ব্যৱহাৰৰ সবিশেষ চাওক" - - - - - - + "আটাইতকৈ শেহতীয়াকৈ %1$s আগতে এক্সেছ কৰা হৈছিল" + "অনুমতি দিয়া হৈছে" + "অস্বীকাৰ কৰা হৈছে" %s দিন %s দিন @@ -136,36 +135,36 @@ - + "এপ্ বিকাশকৰ্তাৰ মতে আপোনাৰ ডেটা:" + "আপুনি যদি এই এপ্ বিকাশকৰ্তাই যেনেকৈ আপোনাৰ ডেটা ব্যৱহাৰ কৰিছে সেই কথা ভাল পোৱা নাই, তেন্তে আপুনি অনুমতিটো অস্বীকাৰ কৰিব পাৰে।" + "ক্লাউডত আপল’ড কৰা হয়" + "আপুনি স্পষ্টভাৱে অনুমতি দিলে ক্লাউডত আপল’ড কৰা হয়" + "বিজ্ঞাপনদাতা বা ব্যৱসায় প্ৰতিষ্ঠানৰ সৈতে শ্বেয়াৰ কৰা হয়" + "আপুনি যেতিয়া স্পষ্টভাৱে অনুমতি দিয়ে তেতিয়া বিজ্ঞাপনদাতা বা ব্যৱসায় প্ৰতিষ্ঠানৰ সৈতে শ্বেয়াৰ কৰা হয়" + "মুদ্ৰাকৰণৰ বাবে ব্যৱহাৰ কৰা হয়" + "আপুনি স্পষ্টভাৱে অনুমতি দিলে মুদ্ৰাকৰণত ব্যৱহাৰ কৰা হয়" + "চিৰকালৰ কাৰণে ছেভ কৰি ৰখা হয় আৰু বিশ্লেষণ কৰা হয়" + "আপুনি নিৰ্দিষ্ট কৰি দিয়া এক সময়সীমা পৰ্যন্ত ছেভ কৰি ৰখা হয় আৰু বিশ্লেষণ কৰা হয়" + + %s সপ্তাহ পৰ্যন্ত ছেভ কৰি ৰখা হয় আৰু বিশ্লেষণ কৰা হয় + %s সপ্তাহ পৰ্যন্ত ছেভ কৰি ৰখা হয় আৰু বিশ্লেষণ কৰা হয় + + "আপোনাৰ ডেটা এপটোৱে কেনেকৈ ব্যৱহাৰ কৰে সেই কথা এপটোৰ বিকাশকৰ্তাই উল্লেখ কৰা নাই।" + + + + + - + + + "ডিফ’ল্ট এপ্" + "কোনো ডিফ’ল্ট এপ্ নাই" + "ফ\'ন এপ্" "এছএমএছ এপ্" "ব্ৰাউজাৰ এপ্" "Gallery এপ্" "Music এপ্‌" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml index 6c813b848..8b405db74 100644 --- a/res/values-az/strings.xml +++ b/res/values-az/strings.xml @@ -95,7 +95,8 @@ "Son 15 dəqiqə" "İcazələrdən istifadə olunmayıb" "Tətbiq icazələri istifadəsi" - "%1$s əvvəl" + "Giriş: %1$s dəfə. Yekun müddət: %2$s. Son istifadə %3$s əvvəl." + "Giriş: %1$s dəfə. Son istifadə %2$s əvvəl." "İcazə verin" "Həmişə icazə verin" "Yalnız tətbiqin istifadəsi zamanı icazə verin" @@ -103,15 +104,11 @@ "%1$s üçün icazə" "%2$s üçün %1$s girişi" "%1$s %2$s adlı məkana %3$s əvvəl daxil oldu." - - + "%1$s üçün %2$s icazəsi əlçatan deyil." "İcazələrin istifadəsi ilə bağlı ətraflı məlumata baxın" - - - - - - + "Axırıncı dəfə %1$s əvvəl əlçatan idi" + "İcazə verilib" + "Ləğv edildi" %s gün 1 gün @@ -136,36 +133,35 @@ - + "Tətbiq developerinin fikrincə datanız:" + "Əgər bu tətbiq developerinin datadan istifadə qaydasını bəyənmirsinizsə, icazəni ləğv edə bilərsiniz." + "Buluda yükləndi" + "İcazə verdiyiniz zaman buluda yükləndi" + "Reklamçılar və ya bizneslərlə paylaşıldı" + "İcazə verdiyiniz zaman ya reklamçılar, ya da bizneslərlə paylaşıldı" + "Monetizasiya üçün istifadə edildi" + "İcazə verdiyiniz zaman monetizasiya üçün istifadə edildi" + "Həmişəlik yadda saxlandı və təhlil edildi" + "Müəyyən etdiyiniz vaxt ərzində yadda saxlandı və təhlil edildi" + + %s həftəlik yadda saxlandı və təhlil edildi + 1 həftəlik yadda saxlandı və təhlil edildi + + "Tətbiq developeri tətbiqin datadan necə istifadə etdiyini müəyyən edə bilmədi." + - + + + + + + "Defolt tətbiqlər" + "Defolt tətbiq yoxdur" + "Tətbiq yoxdur" "Telefon tətbiqi" "SMS tətbiqi" "Brauzer tətbiqi" "Qalereya tətbiqi" "Musiqi tətbiqi" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml index 3fb963499..08ba94030 100644 --- a/res/values-b+sr+Latn/strings.xml +++ b/res/values-b+sr+Latn/strings.xml @@ -96,7 +96,8 @@ "Poslednjih 15 minuta" "Dozvole nisu korišćene" "Korišćenje dozvola za aplik." - "pre %1$s" + "Pristup: %1$s put(a). Ukupno trajanje: %2$s. Poslednji put korišćena pre %3$s." + "Pristup: %1$s put(a). Poslednji put korišćena pre %2$s." "Dozvoli" "Dozvoli uvek" "Dozvoli samo dok se aplikacija koristi" @@ -104,15 +105,11 @@ "Dozvola %1$s" "Pristup dozvoli %1$s za aplikaciju %2$s" "Aplikacija %1$s je pristupila dozvoli %2$s pre %3$s." - - + "Aplikacija %1$s nije pristupila dozvoli %2$s." "Pregledajte detaljne dozvole za korišćenje" - - - - - - + "Najskoriji pristup bio je pre %1$s" + "Dozvoljeno" + "Odbijeno" %s dan %s dana @@ -141,36 +138,36 @@ - + "Programer aplikacije kaže da podaci mogu:" + "Ako vam se ne sviđa kako ovaj programer aplikacije koristi podatke, možete da povučete dozvolu." + "da se otpremaju u klaud" + "da se otpremaju u klaud kada to izričito dozvolite" + "da se dele sa oglašavačima ili preduzećima" + "da se dele sa oglašavačima ili preduzećima kada to izričito dozvolite" + "da se koriste za monetizaciju" + "da se koriste za monetizaciju kada to izričito dozvolite" + "da se čuvaju i analiziraju zauvek" + "da se čuvaju i analiziraju u periodu koji vi navedete" + + da se čuvaju i analiziraju %s nedelju + da se čuvaju i analiziraju %s nedelje + da se čuvaju i analiziraju %s nedelja + + "Programer aplikacije nije naveo kako aplikacija koristi podatke." + - + + + + + + "Podrazumevane aplikacije" + "Nema podrazumevane aplikacije." + "Nema aplikacija" "Aplikacija Telefon" "Aplikacija za SMS" "Aplikacija pregledača" "Aplikacija Galerija" "Aplikacija Muzika" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml index 9f90bb784..fbb34cbeb 100644 --- a/res/values-be/strings.xml +++ b/res/values-be/strings.xml @@ -97,7 +97,8 @@ "За апошнія 15 хвілін" "Без выкарыстання дазволаў" "Выкарыстанне дазволаў праграмы" - "%1$s таму назад" + "Доступ: колькасць разоў – %1$s. Агульная працягласць: %2$s. Апошняе выкарыстанне – %3$s таму назад." + "Доступ: колькасць разоў – %1$s. Апошняе выкарыстанне – %2$s таму назад." "Дазволіць" "Дазволіць у любым рэжыме" "Дазволіць толькі ў актыўным рэжыме праграмы" @@ -105,15 +106,11 @@ "Дазвол \"%1$s\"" "Доступ да дазволу \"%1$s\" для праграмы \"%2$s\"" "Праграма \"%1$s\" атрымала доступ да дазволу \"%2$s\" %3$s таму назад." - - + "Праграма \"%1$s\" не атрымала доступу да функцыі \"%2$s\"." "Прагледзець звесткі пра выкарыстанне дазволаў" - - - - - - + "Апошні доступ – %1$s таму назад" + "Дазволеныя" + "Адмоўленыя" %s дзень %s дні @@ -146,36 +143,37 @@ - + "Паводле звестак распрацоўшчыка вашы даныя могуць:" + "Калі вам не падабаецца, як распрацоўшчык праграмы выкарыстоўвае вашы даныя, вы можаце адмовіць яму ў дазволе." + "Запампоўвацца ў воблака" + "Запампоўвацца ў воблака з вашага яўнага дазволу" + "Абагульвацца з рэкламадаўцамі і кампаніямі" + "Абагульвацца з рэкламадаўцамі і кампаніямі з вашага яўнага дазволу" + "Выкарыстоўваюцца для манетызацыі" + "Выкарыстоўвацца для манетызацыі з вашага яўнага дазволу" + "Заўсёды захоўвацца і аналізавацца" + "Захоўваюцца і аналізуюцца на працягу вызначанага перыяду" + + Захоўвацца і аналізавацца на працягу %s тыдня​ + Захоўвацца і аналізавацца на працягу %s тыдняў + Захоўвацца і аналізавацца на працягу %s тыдняў + Захоўвацца і аналізавацца на працягу %s тыдня​ + + "Распрацоўшчык праграмы не вызначыў, як яна выкарыстоўвае даныя." + - + + + + + + "Стандартныя праграмы" + "Няма стандартных праграм" + "Няма праграм" "Праграма \"Тэлефон\"" "Праграма для SMS" "Браўзер" "Праграма \"Галерэя\"" "Праграма \"Музыка\"" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml index c29e7b180..4e31d6a39 100644 --- a/res/values-bg/strings.xml +++ b/res/values-bg/strings.xml @@ -95,7 +95,8 @@ "Последните 15 минути" "Разрешенията не са използвани" "Използване на разрешенията" - "Преди %1$s" + "Достъп: %1$s пъти. Обща продължителност: %2$s. Последно използване преди %3$s." + "Достъп: %1$s пъти. Последно използване преди %2$s." "Разрешаване" "Разрешаване във всички случаи" "Разрешаване само докато приложението се използва" @@ -103,15 +104,11 @@ "Разрешение за %1$s" "Достъп до %1$s за %2$s" "%1$s осъществи достъп до %2$s ви преди %3$s." - - + "Приложението %1$s не е осъществило достъп до %2$s." "Преглед на подробности за използването на разрешенията" - - - - - - + "Най-скорошният достъп е преди %1$s" + "Разрешено" + "Отказано" %s дни 1 ден @@ -136,36 +133,35 @@ - + "Програмистът на приложението посочва, че данните ви може да:" + "Ако не харесвате как програмистът на това приложение използва данните ви, можете да откажете разрешението." + "Се качват в облака." + "Се качват в облака, когато изрично го разрешите." + "Се споделят с рекламодатели или бизнеси." + "Се споделят с рекламодатели или бизнеси, когато изрично го разрешите." + "Се използват за осигуряване на приходи." + "Се използват за осигуряване на приходи, когато изрично го разрешите." + "Се запазват и анализират завинаги." + "Се запазват и анализират за посочена от вас продължителност." + + Се запазват и анализират за %s седмици. + Се запазват и анализират за 1 седмица. + + "Програмистът на приложението не е посочил как то използва данните ви." + - + + + + + + "Приложения по подразбиране" + "Няма стандартни приложия" + "Няма приложения" "Приложение за телефон" "Приложение за SMS" "Приложение за браузър" "Приложение за галерия" "Приложение за музика" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml index a626c0a15..3be602fb8 100644 --- a/res/values-bn/strings.xml +++ b/res/values-bn/strings.xml @@ -95,7 +95,8 @@ "গত ১৫ মিনিট" "কোন অনুমতির ব্যবহার হয়নি" "অ্যাপের অনুমতির ব্যবহার" - "%1$s আগে" + "অ্যাক্সেস: %1$s বার। মোট সময়সীমা: %2$s%3$sআগে শেষবার ব্যবহার করা হয়েছে।" + "অ্যাক্সেস: %1$s বার। %2$s আগে শেষবার ব্যবহার করা হয়েছে।" "অনুমতি দিন" "সব সময়ের অনুমতি দিন" "অ্যাপ ব্যবহারের সময়ই শুধুমাত্র অনুমতি দিন" @@ -103,15 +104,11 @@ "%1$s অনুমতি" "%2$s-এর জন্য %1$s" "আপনার %2$s %3$s আগে %1$s অ্যাক্সেস করা হয়েছে।" - - + "%1$s আপনার %2$s অ্যাক্সেস করতে পারেনি।" "বিস্তারিত অনুমতির ব্যবহার দেখুন" - - - - - - + "শেষবার %1$s আগে অ্যাক্সেস করা হয়েছে" + "অনুমোদিত" + "প্রত্যাখ্যান করা হয়েছে" %s দিন %s দিন @@ -136,36 +133,35 @@ - + "অ্যাপ ডেভেলপার বলেছেন আপনার ডেটা হয়ত:" + "অ্যাপ ডেভেলপার যেভাবে আপনার ডেটা ব্যবহার করছে তা আপনার পছন্দ না হলে আপনি অনুমতি নাও দিতে পারেন।" + "ক্লাউডে আপলোড করা হয়েছে" + "নির্দিষ্ট অনুমতি দেওয়ায় ক্লাউডে আপলোড করা হয়েছে" + "বিজ্ঞাপনদাতা বা ব্যবসার সঙ্গে শেয়ার করা হয়েছে" + "নির্দিষ্ট অনুমতি দেওয়া হলে বিজ্ঞাপনদাতা বা ব্যবসার সঙ্গে শেয়ার করা হবে" + "উপার্জনের জন্য ব্যবহার করা হয়" + "নির্দিষ্ট অনুমতি দিলে তবেই উপার্জনের জন্য ব্যবহার হয়" + "বিশ্লেষণ করে চিরদিনের জন্য সেভ করা হয়েছে" + "আপনার নির্দিষ্ট করা সময়ের জন্য বিশ্লেষণ করে সেভ করা হয়েছে" + + %s সপ্তাহের জন্য বিশ্লেষণ করে সেভ করা হয়েছে + %s সপ্তাহের জন্য বিশ্লেষণ করে সেভ করা হয়েছে + + "অ্যাপ আপনার ডেটা কীভাবে ব্যবহার করবে তা অ্যাপ ডেভেলপার নির্দিষ্ট করে দেয়নি।" + - + + + + + + "ডিফল্ট অ্যাপ" + "কোনও ডিফল্ট অ্যাপ নেই" + "কোনও অ্যাপ নেই" "ফোন অ্যাপ" "এসএমএস অ্যাপ" "ব্রাউজার অ্যাপ" "গ্যালারি অ্যাপ" "মিউজিক অ্যাপ" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml index d2a3e6f64..4d632688a 100644 --- a/res/values-bs/strings.xml +++ b/res/values-bs/strings.xml @@ -96,7 +96,8 @@ "Posljednjih 15 minuta" "Odobrenje nije upotrijebljeno" "Korišt. dozvole za aplikacije" - "Prije %1$s" + "Pristup: %1$s puta. Ukupno trajanje: %2$s. Zadnji put korištena prije %3$s." + "Pristup: %1$s puta. Zadnji put korištena prije %2$s." "Dozvoli" "Dozvoli svaki put" "Dozvoli samo kada se aplikacija koristi" @@ -104,15 +105,11 @@ "Odobrenje %1$s" "Pristup odobrenju %1$s za aplikaciju %2$s" "Aplikacija %1$s je pristupila odobrenju %2$s prije %3$s." - - + "Aplikacija %1$s nije pristupila vašem odobrenju %2$s." "Vidi detaljno korištenje odobrenja" - - - - - - + "Zadnji pristup je ostvaren prije %1$s" + "Dozvoljeno" + "Odbijeno" %s dan %s dana @@ -141,36 +138,36 @@ - + "Programer aplikacije kaže da vaši podaci mogu biti:" + "Ako vam se ne sviđa način na koji programer aplikacije koristi vaše podatke, možete odbiti odobrenje." + "otpremani u oblak" + "otpremani u oblak kada to vi izričito dozvolite" + "dijeljeni s oglašivačima ili preduzećima" + "dijeljeni s oglašivačima ili preduzećima kada to vi izričito dozvolite" + "korišteni za unovčavanje" + "korišteni za unovčavanje kada to vi izričito dozvolite" + "analizirani i sačuvani zauvijek" + "analizirani i sačuvani na vremenski period koji vi naznačite" + + analizirani i čuvani %s sedmicu + analizirani i čuvani %s sedmice + analizirani i čuvani %s sedmica + + "Programer aplikacije nije naznačio kako aplikacija koristi vaše podatke." + - + + + + + + "Zadane aplikacije" + "Nema zadanih aplikacija" + "Nema aplikacija" "Aplikacija Telefon" "Aplikacija za SMS" "Aplikacija preglednika" "Aplikacija galerije" "Aplikacija za muziku" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml index 11d067acf..1fced50d3 100644 --- a/res/values-ca/strings.xml +++ b/res/values-ca/strings.xml @@ -95,7 +95,8 @@ "Últims 15 minuts" "Cap ús de permisos" "Ús de permisos de l\'aplicació" - "Fa %1$s" + "Accés: %1$s vegades. Durada total: %2$s. Utilitzada per última vegada fa %3$s." + "Accés: %1$s vegades. Utilitzada per última vegada fa %2$s." "Permet" "Permet sempre" "Permet només mentre s\'utilitza l\'aplicació" @@ -103,15 +104,11 @@ "Permís per accedir a %1$s" "Accés de l\'aplicació %2$s a %1$s" "%1$s va accedir fa %3$s a %2$s." - - + "%1$s no ha accedit al permís %2$s." "Mostra dades detallades sobre l\'ús de permisos" - - - - - - + "Accés més recent: fa %1$s" + "Acceptats" + "Denegats" %s dies 1 dia @@ -136,36 +133,35 @@ - + "El desenvolupador de l\'aplicació diu que és possible que es faci el següent amb les teves dades:" + "Si no t\'agrada com fa servir les teves dades el desenvolupador de l\'aplicació, pots denegar el permís." + "Es pengin al núvol" + "Es pengin al núvol quan ho permetis de manera explícita" + "Es comparteixin amb els anunciants o les empreses" + "Es comparteixin amb els anunciants o les empreses quan ho permetis de manera explícita" + "Es facin servir per obtenir ingressos" + "Es facin servir per obtenir ingressos quan ho permetis de manera explícita" + "Es desin i s\'analitzin sempre" + "Es desin i s\'analitzin durant el període que especifiquis" + + Es desin i s\'analitzin durant %s setmanes + Es desin i s\'analitzin durant 1 setmana + + "El desenvolupador de l\'aplicació no ha especificat com fa servir les teves dades l\'aplicació." + - + + + + + + "Aplicacions predeterminades" + "Cap aplicació predeterminada" + "Cap aplicació" "Aplicació Telèfon" "Aplicació d\'SMS" "Aplicació de navegador" "Aplicació Galeria" "Aplicació Música" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml index 4e44fe91b..8d8728dfe 100644 --- a/res/values-cs/strings.xml +++ b/res/values-cs/strings.xml @@ -97,7 +97,8 @@ "Posledních 15 minut" "Žádné využití oprávnění" "Využití oprávnění aplikace" - "Před %1$s" + "Přístup: %1$s×. Celkový čas: %2$s. Naposledy použito před %3$s." + "Přístup: %1$s×. Naposledy použito před %2$s." "Povolit" "Povolit vždy" "Povolit jen během používání aplikace" @@ -105,15 +106,11 @@ "Oprávnění %1$s" "Přístup k údajům %1$s pro aplikaci %2$s" "Aplikace %1$s získala před %3$s přístup k těmto údajům: %2$s." - - + "Aplikace %1$s nezískala přístup k oprávnění %2$s." "Zobrazit podrobné využití oprávnění" - - - - - - + "Poslední přístup před %1$s" + "Povoleno" + "Zamítnuto" %s dny %s dne @@ -146,36 +143,37 @@ - + "Vývojář aplikace informuje, že vaše data mohou být:" + "Pokud se vám nelíbí, jak vývojář této aplikace vaše data využívá, můžete oprávnění zamítnout." + "Nahrána do cloudu" + "Nahrána do cloudu, když to výslovně povolíte" + "Sdílena s inzerentem nebo firmou" + "Sdílena s inzerenty nebo firmami, když to výslovně povolíte" + "Používána k monetizaci" + "Používána k monetizaci, když to výslovně povolíte" + "Uložena a analyzována po neomezenou dobu" + "Uložena a analyzována po dobu, kterou určíte" + + Uložena a analyzována po dobu %s týdnů + Uložena a analyzována po dobu %s týdne + Uložena a analyzována po dobu %s týdnů + Uložena a analyzována po dobu jednoho týdne + + "Vývojář aplikace neurčil, jak aplikace využívá vaše data." + - + + + + + + "Výchozí aplikace" + "Žádné výchozí aplikace" + "Žádné aplikace" "Aplikace Telefon" "Aplikace pro SMS" "Prohlížeč" "Aplikace Galerie" "Aplikace Hudba" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml index 3aaef14bd..b4f5ac3a2 100644 --- a/res/values-da/strings.xml +++ b/res/values-da/strings.xml @@ -95,7 +95,8 @@ "De seneste 15 minutter" "Ingen brug af tilladelsen" "Brug af apptilladelser" - "For %1$s siden" + "Adgang: %1$s gange. Samlet varighed: %2$s. Senest brugt for %3$s siden." + "Adgang: %1$s gange. Senest brugt for %2$s siden." "Tillad" "Tillad altid" "Tillad kun, mens appen bruges" @@ -103,15 +104,11 @@ "Tilladelse for %1$s" "Adgang til %1$s for %2$s" "%1$s anvendte din/dit %2$s for %3$s siden." - - + "%1$s har ikke adgang til din %2$s." "Se detaljeret brug af tilladelser" - - - - - - + "Seneste adgang: For %1$s siden" + "Tilladt" + "Afvist" %s dag %s dage @@ -136,36 +133,35 @@ - + "Appudvikleren siger, at dine data kan:" + "Hvis du ikke kan lide den måde, som appudvikleren bruger dine data på, kan du afvise tilladelsen." + "Uploades til skyen" + "Uploades til skyen, når du udtrykkeligt giver tilladelse" + "Deles med annoncører og virksomheder" + "Deles med annoncører og virksomheder, når du udtrykkeligt giver tilladelse" + "Bruges til indtægtsgenerering" + "Bruges til indtægtsgenerering, når du udtrykkeligt giver tilladelse" + "Gemmes og analyseres for evigt" + "Gemmes og analyseres i en tidsperiode, som du angiver" + + Gemmes og analyseres i %s uge + Gemmes og analyseres i %s uger + + "Appudvikleren har ikke angivet, hvordan appen bruger dine data." + - + + + + + + "Standardapps" + "Ingen standardapps." + "Ingen apps" "Appen Opkald" "Sms-app" "Browserapp" "Galleriapp" "Musikapp" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index 0909cb319..3fd7352a8 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -95,7 +95,8 @@ "Letzte 15 Minuten" "Keine Berechtigungen verwendet" "Nutzung von App-Berechtigungen" - "vor %1$s" + "Zugriff: %1$s Mal. Gesamtdauer: %2$s. Zuletzt verwendet vor %3$s." + "Zugriff: %1$s Mal. Zuletzt verwendet vor %2$s" "Zulassen" "Immer zulassen" "Nur zulassen, wenn die App verwendet wird" @@ -103,15 +104,11 @@ "Berechtigung \"%1$s\"" "Zugriff auf %1$s für %2$s" "%1$s hat vor %3$s auf %2$s zugegriffen." - - + "%1$s hat nicht auf %2$s zugegriffen." "Details zur Berechtigungsnutzung ansehen" - - - - - - + "Letzter Zugriff vor %1$s" + "Zulässig" + "Abgelehnt" %s Tage 1 Tag @@ -136,36 +133,35 @@ - + "Laut des App-Entwicklers können deine Daten:" + "Wenn dir nicht gefällt, wie dieser App-Entwickler deine Daten verwendet, kannst du ihm die Berechtigung verweigern." + "In die Cloud hochgeladen" + "In die Cloud hochgeladen, wenn du es ausdrücklich erlaubst" + "Für Werbetreibende und Unternehmen freigegeben" + "Für Werbetreibende und Unternehmen freigegeben, wenn du es ausdrücklich erlaubst" + "Zur Monetarisierung verwendet" + "Zur Monetarisierung verwendet, wenn du es ausdrücklich erlaubst" + "Für immer gespeichert und analysiert" + "Für eine von dir angegebene Dauer gespeichert und analysiert" + + Für %s Wochen gespeichert und analysiert + Für 1 Woche gespeichert und analysiert + + "Der App-Entwickler hat nicht angegeben, wie deine Daten in der App verwendet werden." + - + + + + + + "Standard-Apps" + "Keine Standard-Apps" + "Keine Apps" "Telefon-App" "SMS-App" "Browser-App" "Galerie App" "Musik App" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml index ff40d3017..3fb78306f 100644 --- a/res/values-el/strings.xml +++ b/res/values-el/strings.xml @@ -95,7 +95,8 @@ "Τελευταία 15 λεπτά" "Καμία χρήση δικαιωμάτων" "Χρήση αδειών εφαρμογής" - "%1$s πριν" + "Πρόσβαση: %1$s φορές. Συνολική διάρκεια: %2$s. Τελευταία χρήση πριν από %3$s." + "Πρόσβαση: %1$s φορές. Τελευταία χρήση πριν από %2$s." "Να επιτρέπεται" "Να επιτρέπεται πάντα" "Να επιτρέπεται μόνο όταν χρησιμοποιείται η εφαρμογή" @@ -103,15 +104,11 @@ "Άδεια %1$s" "Πρόσβαση σε %1$s για την εφαρμογή %2$s" "Η εφαρμογή %1$s είχε πρόσβαση σε %2$s πριν από %3$s." - - + "Η εφαρμογή %1$s δεν απέκτησε πρόσβαση σε %2$s." "Προβολή λεπτομερούς χρήσης αδειών" - - - - - - + "Πιο πρόσφατη πρόσβαση πριν από %1$s" + "Επιτρέπονται" + "Απορρίφθηκαν" %s ημέρες 1 ημέρα @@ -136,36 +133,35 @@ - + "Ο προγραμματιστής της εφαρμογής λέει ότι τα δεδομένα σας μπορεί να:" + "Αν δεν σας αρέσει ο τρόπος με τον οποίο ο προγραμματιστής της εφαρμογής χρησιμοποιεί τα δεδομένα σας, μπορείτε να απορρίψετε την άδεια." + "Να μεταφορτωθούν στο cloud" + "Να μεταφορτωθούν στο cloud όταν το επιτρέψετε ρητά" + "Να κοινοποιηθούν σε διαφημιζόμενους ή επιχειρήσεις" + "Να κοινοποιηθούν σε διαφημιζόμενους ή επιχειρήσεις όταν το επιτρέψετε ρητά" + "Χρησιμοποιηθούν για τη δημιουργία εσόδων" + "Χρησιμοποιηθούν για τη δημιουργία εσόδων όταν το επιτρέψετε ρητά" + "Αποθηκευτούν και να αναλύονται για πάντα" + "Αποθηκευτούν και να αναλύονται για την περίοδο που προσδιορίσατε" + + Αποθηκευτούν και να αναλύονται για %s εβδομάδες + Αποθηκευτούν και να αναλύονται για 1 εβδομάδα + + "Ο προγραμματιστής της εφαρμογής δεν προσδιόρισε τον τρόπο με τον οποίο η εφαρμογή χρησιμοποιεί τα δεδομένα σας." + - + + + + + + "Προεπιλεγμένες εφαρμογές" + "Καμία προεπιλεγμένη εφαρμογή" + "Δεν υπάρχουν εφαρμογές" "Εφαρμογή \"Τηλέφωνο\"" "Εφαρμογή SMS" "Εφαρμ. προγράμματος περιήγησης" "Εφαρμογή Gallery" "Εφαρμογή μουσικής" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml index f23a94f7e..36319e51b 100644 --- a/res/values-en-rAU/strings.xml +++ b/res/values-en-rAU/strings.xml @@ -95,7 +95,8 @@ "Last 15 minutes" "No permission usages" "App permissions usage" - "%1$s ago" + "Access: %1$s times. Total duration: %2$s. Last used %3$s ago." + "Access: %1$s times. Last used %2$s ago." "Allow" "Allow all the time" "Allow only while the app is in use" @@ -103,15 +104,11 @@ "%1$s permission" "%1$s access for %2$s" "%1$s accessed your %2$s %3$s ago." - - + "%1$s has not accessed your %2$s." "View detailed permissions usage" - - - - - - + "Most recent access %1$s ago" + "Allowed" + "Denied" %s days 1 day @@ -136,36 +133,35 @@ - + "The app developer says that your data may be:" + "If you don’t like how this app developer is using your data you can deny the permission." + "Uploaded to cloud" + "Uploaded to cloud when you explicitly allow it" + "Shared with advertisers or businesses" + "Shared with advertisers or businesses when you explicitly allow it" + "Used for monetisation" + "Used for monetisation when you explicitly allow it" + "Saved and analysed forever" + "Saved and analysed for a duration that you specify" + + Saved and analysed for %s weeks + Saved and analysed for 1 week + + "The app developer did not specify how the app uses your data." + - + + + + + + "Default apps" + "No default apps" + "No apps" "Phone app" "SMS app" "Browser app" "Gallery app" "Music app" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml index f23a94f7e..36319e51b 100644 --- a/res/values-en-rCA/strings.xml +++ b/res/values-en-rCA/strings.xml @@ -95,7 +95,8 @@ "Last 15 minutes" "No permission usages" "App permissions usage" - "%1$s ago" + "Access: %1$s times. Total duration: %2$s. Last used %3$s ago." + "Access: %1$s times. Last used %2$s ago." "Allow" "Allow all the time" "Allow only while the app is in use" @@ -103,15 +104,11 @@ "%1$s permission" "%1$s access for %2$s" "%1$s accessed your %2$s %3$s ago." - - + "%1$s has not accessed your %2$s." "View detailed permissions usage" - - - - - - + "Most recent access %1$s ago" + "Allowed" + "Denied" %s days 1 day @@ -136,36 +133,35 @@ - + "The app developer says that your data may be:" + "If you don’t like how this app developer is using your data you can deny the permission." + "Uploaded to cloud" + "Uploaded to cloud when you explicitly allow it" + "Shared with advertisers or businesses" + "Shared with advertisers or businesses when you explicitly allow it" + "Used for monetisation" + "Used for monetisation when you explicitly allow it" + "Saved and analysed forever" + "Saved and analysed for a duration that you specify" + + Saved and analysed for %s weeks + Saved and analysed for 1 week + + "The app developer did not specify how the app uses your data." + - + + + + + + "Default apps" + "No default apps" + "No apps" "Phone app" "SMS app" "Browser app" "Gallery app" "Music app" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml index f23a94f7e..36319e51b 100644 --- a/res/values-en-rGB/strings.xml +++ b/res/values-en-rGB/strings.xml @@ -95,7 +95,8 @@ "Last 15 minutes" "No permission usages" "App permissions usage" - "%1$s ago" + "Access: %1$s times. Total duration: %2$s. Last used %3$s ago." + "Access: %1$s times. Last used %2$s ago." "Allow" "Allow all the time" "Allow only while the app is in use" @@ -103,15 +104,11 @@ "%1$s permission" "%1$s access for %2$s" "%1$s accessed your %2$s %3$s ago." - - + "%1$s has not accessed your %2$s." "View detailed permissions usage" - - - - - - + "Most recent access %1$s ago" + "Allowed" + "Denied" %s days 1 day @@ -136,36 +133,35 @@ - + "The app developer says that your data may be:" + "If you don’t like how this app developer is using your data you can deny the permission." + "Uploaded to cloud" + "Uploaded to cloud when you explicitly allow it" + "Shared with advertisers or businesses" + "Shared with advertisers or businesses when you explicitly allow it" + "Used for monetisation" + "Used for monetisation when you explicitly allow it" + "Saved and analysed forever" + "Saved and analysed for a duration that you specify" + + Saved and analysed for %s weeks + Saved and analysed for 1 week + + "The app developer did not specify how the app uses your data." + - + + + + + + "Default apps" + "No default apps" + "No apps" "Phone app" "SMS app" "Browser app" "Gallery app" "Music app" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml index f23a94f7e..36319e51b 100644 --- a/res/values-en-rIN/strings.xml +++ b/res/values-en-rIN/strings.xml @@ -95,7 +95,8 @@ "Last 15 minutes" "No permission usages" "App permissions usage" - "%1$s ago" + "Access: %1$s times. Total duration: %2$s. Last used %3$s ago." + "Access: %1$s times. Last used %2$s ago." "Allow" "Allow all the time" "Allow only while the app is in use" @@ -103,15 +104,11 @@ "%1$s permission" "%1$s access for %2$s" "%1$s accessed your %2$s %3$s ago." - - + "%1$s has not accessed your %2$s." "View detailed permissions usage" - - - - - - + "Most recent access %1$s ago" + "Allowed" + "Denied" %s days 1 day @@ -136,36 +133,35 @@ - + "The app developer says that your data may be:" + "If you don’t like how this app developer is using your data you can deny the permission." + "Uploaded to cloud" + "Uploaded to cloud when you explicitly allow it" + "Shared with advertisers or businesses" + "Shared with advertisers or businesses when you explicitly allow it" + "Used for monetisation" + "Used for monetisation when you explicitly allow it" + "Saved and analysed forever" + "Saved and analysed for a duration that you specify" + + Saved and analysed for %s weeks + Saved and analysed for 1 week + + "The app developer did not specify how the app uses your data." + - + + + + + + "Default apps" + "No default apps" + "No apps" "Phone app" "SMS app" "Browser app" "Gallery app" "Music app" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-en-rXC/strings.xml b/res/values-en-rXC/strings.xml index 869697313..722d60381 100644 --- a/res/values-en-rXC/strings.xml +++ b/res/values-en-rXC/strings.xml @@ -95,7 +95,8 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‏‎‏‏‏‎‎‎‏‎‏‏‎‏‎‎‎‏‏‎‎‎‎‎‎‎‏‏‎‎‎‎‎‏‎‎‏‏‎‏‎‎‏‎‎‏‎‏‎‎‎‎Last 15 minutes‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‏‎‏‏‎‎‏‎‏‏‎‏‏‎‎‎‎‎‏‏‏‎‎‎‎‏‎‎‎‎‏‏‎‏‏‏‎‏‎‏‎‎‏‏‎‏‏‎‏‏‎‏‏‎‏‏‎No permission usages‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‏‎‎‎‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‏‏‎‏‎‏‎‎‏‏‎‎‎‏‏‎‎‏‏‏‎‏‎‏‎‏‎‎‏‏‏‏‎‎App permissions usage‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‏‎‎‏‏‏‎‎‎‏‎‏‎‎‎‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‏‎‎‎‏‏‏‎‎‏‎‏‏‎‎‏‏‎‎‎‏‎‏‏‏‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ ago‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‏‏‎‎‏‏‎‏‏‏‏‎‎‎‎‎‎‏‎‎‏‏‏‎‏‏‎‎‏‏‎‏‎‎‎‏‏‏‎‏‏‏‎‎‏‎‎‏‎‏‏‎‎Access: ‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ times. Total duration: ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎. Last used ‎‏‎‎‏‏‎%3$s‎‏‎‎‏‏‏‎ ago.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‏‏‏‏‎‎‎‏‎‎‎‎‏‏‏‎‎‏‏‎‏‏‎‎‏‎‎‎‏‏‏‎‏‏‏‏‎‎‏‏‏‎‏‎‏‎‎‎Access: ‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ times. Last used ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎ ago.‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‏‏‎‏‏‎‏‏‎‏‏‏‏‏‎‏‎‎‏‎‎‎‎‎‏‏‏‎‎‏‏‎‎‎‏‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‎Allow‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‏‏‎‏‏‏‎‎‏‎‏‎‏‏‏‎‎‎‎‏‎‏‎‎‏‎‏‎‏‎‎‎‏‎‎‏‎‏‏‎‎‏‏‏‏‎‏‏‎‏‏‏‏‏‎‎‎Allow all the time‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‏‎‏‏‎‎‏‎‏‎‏‏‏‎‏‎‏‏‎‎‎‎‎‏‎‎‏‎‎‏‎‎‎‏‎‏‎‏‎‎‎‎‎‎‎‎‎‎‎‎‎‏‏‎‏‎Allow only while the app is in use‎‏‎‎‏‎" @@ -129,13 +130,6 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‎‏‏‎‎‏‎‏‎‏‏‏‏‏‎‏‎‏‏‏‎‏‎‏‏‎‏‏‎‏‎‏‏‎‏‎‏‎‎‎‎‏‎‎‎‎‎‎‏‏‏‏‎Permission reminders‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‎‏‎‏‎‏‎‎‏‎‎‏‏‏‏‎‏‏‎‏‏‏‎‎‏‎‎‎‎‎‎‎‏‎‎‎‎‏‎‎‏‎‏‏‏‎‏‏‏‎‏‎‏‏‏‎‎‎‏‎‎‏‏‎%s‎‏‎‎‏‏‏‎ has been using your location‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‏‎‏‏‏‎‎‏‎‏‎‏‏‎‎‏‎‏‏‎‏‎‎‎‏‎‏‎‏‎‎‎‎‎‎‎‎‏‎‎‎‏‏‎‎‎‏‎‎‏‏‏‎‎‎This app can always access your location. Tap to change.‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‏‏‏‏‏‎‎‏‏‎‎‏‎‎‏‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‏‏‏‎‏‏‎‏‏‏‏‏‏‎‏‎‎‎‏‎‎‎Default apps‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‏‏‏‎‏‏‏‏‎‎‏‏‏‎‎‎‏‎‏‎‎‏‏‏‎‎‏‎‎‏‎‏‎‎‏‏‎‎‏‏‎‏‏‏‏‏‏‏‏‎‎‎‎No default apps‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‎‏‏‎‏‏‏‏‎‎‎‎‎‎‎‏‏‏‎‏‏‎‏‏‏‎‎‏‎‎‏‎‎‏‏‎‎‏‏‎‏‎‏‏‎‎‏‏‎‎‎‏‏‏‎‏‎Phone app‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‏‏‏‏‎‎‎‎‏‏‏‏‏‎‎‎‏‎‎‏‎‎‏‏‎‏‎‏‏‎‏‏‏‎‏‏‏‏‎‎‏‏‏‎‎‏‎‎SMS app‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‏‏‏‎‏‏‏‎‎‎‏‎‏‏‎‏‎‎‏‎‏‎‎‏‎‏‎‏‏‎‎‎‎‏‎‎‏‎‏‎‎‏‎‎‏‏‏‎‏‎‏‎‎‎‏‎Browser app‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‎‎‏‏‏‎‎‏‎‎‎‏‎‏‎‏‎‎‎‏‎‏‎‎‎‎‎‎‎‎‏‏‏‎‏‏‎‏‏‏‎‎‎‏‎‎‎‎‎‎‏‎‎‏‎Gallery app‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‏‎‎‎‎‏‏‏‏‎‎‎‎‏‏‏‏‏‎‎‎‏‏‎‏‎‏‎‎‎‏‎‏‏‎‏‏‎‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎Music app‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‎‏‎‏‏‎‎‎‏‏‏‏‏‎‏‏‎‎‎‏‏‎‏‏‎‎‎‎‎‏‏‎‏‎‏‏‏‎‏‏‏‏‎‏‏‏‎‏‏‏‏‏‎The app developer says your data may be:‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎‏‏‎‏‏‏‏‏‎‏‎‏‏‏‏‎‎‎‏‏‎‏‎‎‎‎‎‎‎‏‎‏‏‏‏‎‏‎‏‏‏‏‏‏‎‎‏‏‏‎‏‏‎‏‎‎‎If you don’t like how this app developer is using your data you can deny the permission.‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‏‎‏‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‏‎‏‏‎‎‏‏‎‎‎‏‎‏‎‏‎‎‎‏‏‎‎‎‎‎‏‎‏‎‏‏‏‏‎‏‏‎‎Uploaded to cloud‎‏‎‎‏‎" @@ -151,4 +145,20 @@ ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‎‏‎‏‏‎‏‎‏‏‏‏‏‏‏‎‎‎‏‎‎‎‏‎‏‏‏‎‎‏‏‎‎‏‏‎‏‏‎‏‎‎‏‏‏‏‎‎‏‎‎‏‏‏‏‎‎Saved and analyzed for 1 week‎‏‎‎‏‎ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‎‎‎‎‏‎‏‏‎‎‏‎‎‎‎‎‏‏‏‏‎‏‎‎‎‎‏‎‏‏‎‎‏‏‏‎‎‏‏‏‎‏‎‎‏‎‎‏‎‏‎‎‏‏‎The app developer did not specify how the app uses your data.‎‏‎‎‏‎" + + + + + + + + + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‏‏‏‏‏‎‎‏‏‎‎‏‎‎‏‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‏‏‏‎‏‏‎‏‏‏‏‏‏‎‏‎‎‎‏‎‎‎Default apps‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‏‏‏‎‏‏‏‏‎‎‏‏‏‎‎‎‏‎‏‎‎‏‏‏‎‎‏‎‎‏‎‏‎‎‏‏‎‎‏‏‎‏‏‏‏‏‏‏‏‎‎‎‎No default apps‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‎‏‏‎‏‎‏‏‏‎‏‎‏‎‎‏‏‏‏‏‎‏‎‏‎‏‏‎‎‏‎‏‏‎‎‏‏‎‎‎‏‏‎‎‏‎‎‏‏‎‎‎‎‎‏‎No apps‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‎‏‏‎‏‏‏‏‎‎‎‎‎‎‎‏‏‏‎‏‏‎‏‏‏‎‎‏‎‎‏‎‎‏‏‎‎‏‏‎‏‎‏‏‎‎‏‏‎‎‎‏‏‏‎‏‎Phone app‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‏‏‏‏‎‎‎‎‏‏‏‏‏‎‎‎‏‎‎‏‎‎‏‏‎‏‎‏‏‎‏‏‏‎‏‏‏‏‎‎‏‏‏‎‎‏‎‎SMS app‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‏‏‏‎‏‏‏‎‎‎‏‎‏‏‎‏‎‎‏‎‏‎‎‏‎‏‎‏‏‎‎‎‎‏‎‎‏‎‏‎‎‏‎‎‏‏‏‎‏‎‏‎‎‎‏‎Browser app‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‎‎‏‏‏‎‎‏‎‎‎‏‎‏‎‏‎‎‎‏‎‏‎‎‎‎‎‎‎‎‏‏‏‎‏‏‎‏‏‏‎‎‎‏‎‎‎‎‎‎‏‎‎‏‎Gallery app‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‏‎‎‎‎‏‏‏‏‎‎‎‎‏‏‏‏‏‎‎‎‏‏‎‏‎‏‎‎‎‏‎‏‏‎‏‏‎‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎Music app‎‏‎‎‏‎" diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml index d05ff8c02..8b5fbfcdf 100644 --- a/res/values-es-rUS/strings.xml +++ b/res/values-es-rUS/strings.xml @@ -95,7 +95,8 @@ "Últimos 15 minutos" "Ningún uso de permisos" "Uso de permisos de la app" - "Hace %1$s" + "Acceso: %1$s veces Duración total: %2$s. Último uso: hace %3$s" + "Acceso: %1$s veces Último uso: hace %2$s" "Permitir" "Permitir todo el tiempo" "Permitir solo cuando la app está en uso" @@ -103,15 +104,11 @@ "Permiso de %1$s" "Acceso de %1$s a %2$s" "%1$s accedió a tu %2$s hace %3$s." - - + "%1$s no accedió a tus %2$s." "Ver uso de permisos detallado" - - - - - - + "El último acceso fue hace %1$s" + "Permitidos" + "Rechazado" %s días 1 día @@ -136,36 +133,35 @@ - + "El desarrollador de la app menciona las siguientes posibilidades para tus datos:" + "Si no te gusta la manera en que el desarrollador de esta app usa tus datos, puedes denegar el permiso." + "Se suben a la nube" + "Se suben a la nube cuando lo permites explícitamente" + "Se comparten con anunciantes o empresas" + "Se comparten con anunciantes o empresas cuando lo permites explícitamente" + "Se usan para monetización" + "Se usan para monetización cuando lo permites explícitamente" + "Se guardan y se analizan por siempre" + "Se guardan y se analizan durante el tiempo que especifiques" + + Se guardan y se analizan durante %s semanas + Se guardan y se analizan durante 1 semana + + "El desarrollador de la app no especificó la manera en que la app usa tus datos." + - + + + + + + "Apps predeterminadas" + "Sin apps predeterminadas" + "Sin apps" "App de teléfono" "app de SMS" "App de navegador" "App de Galería" "App de Música" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index b7dc04c74..a542aac83 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -95,7 +95,8 @@ "Últimos 15 minutos" "No se han usado los permisos" "Uso permisos de la aplicación" - "Hace %1$s" + "Acceso: %1$s veces. Duración total: %2$s. Último uso: hace %3$s." + "Acceso: %1$s veces. Último uso: hace %2$s." "Permitir" "Permitir siempre" "Permitir solo mientras las aplicaciones están en uso" @@ -103,15 +104,11 @@ "Permiso de %1$s" "Acceso de %2$s a tu %1$s" "%1$s ha accedido a tu %2$s hace %3$s." - - + "%1$s no ha accedido a tu %2$s." "Ver el uso de permisos detallado" - - - - - - + "Acceso más reciente: hace %1$s" + "Permitidos" + "Denegados" %s días 1 día @@ -136,36 +133,35 @@ - + "El desarrollador de la aplicación dice que tus datos se podrán:" + "Si no estás de acuerdo con el uso que hace de tus datos el desarrollador de esta aplicación, puedes denegarle el permiso." + "Subir a la nube" + "Subir a la nube si das tu consentimiento explícito" + "Compartir con anunciantes o empresas" + "Compartir con anunciantes o empresas si das tu consentimiento explícito" + "Usar para obtener ingresos" + "Usar para obtener ingresos si das tu consentimiento explícito" + "Guardar y analizar durante un tiempo ilimitado" + "Guardar y analizar durante el tiempo que especifiques" + + Guardar y analizar durante %s semanas + Guardar y analizar durante 1 semana + + "El desarrollador no ha especificado cómo utilizará tus datos la aplicación." + - + + + + + + "Aplicaciones predeterminadas" + "Ninguna app predeterminada" + "No hay aplicaciones" "Aplicación de teléfono" "Aplicación de SMS" "Aplicación de navegador" "Aplicación de galería" "Aplicación de música" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml index a9703c305..6b333e7ec 100644 --- a/res/values-et/strings.xml +++ b/res/values-et/strings.xml @@ -95,7 +95,8 @@ "Viimased 15 minutit" "Lube pole kasutatud" "Rakenduse lubade kasutus" - "%1$s tagasi" + "Juurdepääs: %1$s korda. Kogukestus: %2$s. Viimati kasutati %3$s tagasi." + "Juurdepääs: %1$s korda. Viimati kasutati %2$s tagasi." "Luba" "Luba alati" "Luba ainult rakenduse kasutamise ajal" @@ -103,15 +104,11 @@ "Luba %1$s" "Rakenduse %2$s juurdepääs loale %1$s" "Rakendus %1$s pääses loale %2$s juurde %3$s tagasi." - - + "%1$s pole teie loale %2$s juurde pääsenud." "Kuva lubade kasutamise üksikasjad" - - - - - - + "Viimati pääseti juurde %1$s tagasi" + "Lubatud" + "Keeldutud" %s päeva 1 päev @@ -136,36 +133,35 @@ - + "Rakenduse arendaja ütleb, et teie andmetega võidakse teha järgmist." + "Kui teile ei meeldi, kuidas rakenduse arendaja teie andmeid kasutab, ei pea te luba andma." + "Laaditakse pilve üles" + "Laaditakse pilve üles, kui seda sõnaselgelt lubate" + "Jagatakse reklaamijate või ettevõtetega" + "Jagatakse reklaamijate või ettevõtetega, kui seda sõnaselgelt lubate" + "Kasutatakse monetiseerimiseks" + "Kasutatakse monetiseerimiseks, kui seda sõnaselgelt lubate" + "Analüüsitakse ja salvestatakse igaveseks" + "Analüüsitakse ja salvestatakse teie määratud ajaks" + + Analüüsitakse ja salvestatakse %s nädalaks + Analüüsitakse ja salvestatakse 1 nädalaks + + "Rakenduse arendaja ei täpsustanud, kuidas rakendus teie andmeid kasutab." + - + + + + + + "Vaikerakendused" + "Vaikerakendusi pole" + "Rakendusi pole" "Telefonirakendus" "SMS-i rakendus" "Brauserirakendus" "Galeriirakendus" "Muusikarakendus" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml index 3fca8e3c7..7c003b795 100644 --- a/res/values-eu/strings.xml +++ b/res/values-eu/strings.xml @@ -95,7 +95,8 @@ "Azken 15 minutuetan" "Ez da eskatu baimenik" "Aplikazio-baimenen erabilera" - "Duela %1$s" + "Sarbidea: %1$s aldiz. Iraupena, guztira: %2$s. Duela %3$s erabili zen azken aldiz." + "Sarbidea: %1$s aldiz. Duela %2$s erabili zen azken aldiz." "Baimendu" "Baimendu beti" "Baimendu aplikazioa erabiltzen ari zarenean soilik" @@ -132,13 +133,6 @@ - "Aplikazio lehenetsiak" - "Ez dago aplikazio lehenetsirik" - "Telefonoa" - "SMS" - "Arakatzailea" - "Galeria aplikazioa" - "Musika aplikazioa" "Aplikazioaren garatzaileak datuekin hau gertatuko dela dio:" "Ez bazaizu gustatzen aplikazioaren garatzaileak zure datuak nola erabiltzen dituen, baimena ukatzeko aukera duzu." "Hodeira kargatuko dira" @@ -154,4 +148,20 @@ Astebetez gorde eta analizatuko dira "Aplikazioaren garatzaileak ez du zehaztu aplikazioak nola erabiltzen dituen datuak." + + + + + + + + + "Aplikazio lehenetsiak" + "Ez dago aplikazio lehenetsirik" + "Ez dago aplikaziorik" + "Telefonoa" + "SMS" + "Arakatzailea" + "Galeria aplikazioa" + "Musika aplikazioa" diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml index f2613fe5e..5690f198f 100644 --- a/res/values-fa/strings.xml +++ b/res/values-fa/strings.xml @@ -95,7 +95,8 @@ "۱۵ دقیقه اخیر" "هیچ مجوزی استفاده نشده است" "استفاده از مجوزهای برنامه" - "%1$s قبل" + "دسترسی: %1$s بار. کل مدت: %2$s. آخرین استفاده: %3$s قبل." + "دسترسی: %1$s بار. آخرین استفاده: %2$s قبل." "مجاز" "همیشه مجاز بودن" "مجاز بودن تنها هنگام استفاده از برنامه" @@ -103,15 +104,11 @@ "مجوز %1$s" "دسترسی %1$s برای %2$s" "%1$s %3$s پیش به %2$s دسترسی یافت." - - + "%1$s به %2$s شما دسترسی پیدا نکرده است." "مشاهده استفاده از مجوزها با جزئیات" - - - - - - + "جدیدترین دسترسی %1$s پیش" + "مجاز" + "رد شد" %s روز %s روز @@ -136,36 +133,35 @@ - + "برنامه‌نویس برنامه می‌گوید ممکن است داده‌هایتان به این صورت باشد:" + "اگر نحوه استفاده برنامه‌نویس برنامه از داده‌هایتان را دوست ندارید، می‌توانید مجوز را رد کنید." + "‏بارگذاری‌شده در cloud" + "‏بارگذاری‌شده در cloud وقتی صراحتاً آن را مجاز می‌کنید" + "هم‌رسانی‌شده با آگهی‌دهنده‌ها و کسب‌وکارها" + "هم‌رسانی‌شده با آگهی‌دهنده‌ها و کسب‌وکارها وقتی صراحتاً آن را مجاز می‌کنید" + "استفاده‌شده برای کسب درآمد" + "استفاده‌شده برای کسب درآمد وقتی صراحتاً آن را مجاز می‌کنید" + "ذخیره‌شده و تجزیه‌وتحلیل‌شده برای همیشه" + "ذخیره‌شده و تجزیه‌وتحلیل‌شده برای مدت‌زمانی که مشخص کرده‌اید" + + ذخیره‌شده و تجزیه‌وتحلیل‌شده برای %s هفته + ذخیره‌شده و تجزیه‌وتحلیل‌شده برای %s هفته + + "برنامه‌نویس برنامه مشخص نکرده است برنامه چگونه از داده‌هایتان استفاده می‌کند." + - + + + + + + "برنامه‌های پیش‌فرض" + "هیچ برنامه پیش‌فرضی وجود ندارد." + "برنامه‌ای موجود نیست" "برنامه تلفن" "برنامه پیامک" "برنامه مرورگر" "برنامه گالری" "برنامه موسیقی" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml index 696a0cce4..9508c8dfd 100644 --- a/res/values-fi/strings.xml +++ b/res/values-fi/strings.xml @@ -95,7 +95,8 @@ "Viimeiset 15 minuuttia" "Käyttöoikeuksia ei käytetty" "Sovelluksen käyttöoikeudet" - "%1$s sitten" + "Käyttö: %1$s kertaa. Kokonaiskesto: %2$s. Käytetty viimeksi %3$s sitten." + "Käyttö: %1$s kertaa. Käytetty viimeksi %2$s sitten." "Salli" "Salli aina" "Salli vain, kun sovellusta käytetään" @@ -103,15 +104,11 @@ "Käyttöoikeus: %1$s" "%2$s pyytää käyttöoikeutta: %1$s" "%2$s oli sovelluksen (%1$s) käytössä %3$s sitten" - - + "%1$s ei ole käyttänyt kohdetta %2$s." "Näytä tarkat käyttöoikeustiedot" - - - - - - + "Edellinen käyttökerta %1$s sitten" + "Sallittu" + "Kielletty" %s päivää 1 päivä @@ -136,36 +133,35 @@ - + "Sovelluskehittäjän mukaan dataasi saatetaan" + "Jos et pidä tämän kehittäjän datankäyttötavoista, voit kieltää käyttöoikeuden." + "ladata pilveen" + "ladata pilveen, kun sallit sen erikseen" + "jakaa mainostajille tai yrityksille" + "jakaa mainostajille tai yrityksille, kun sallit sen erikseen" + "käyttää tulouttamiseen" + "käyttää tulouttamiseen, kun sallit sen erikseen" + "tallentaa ja analysoida pysyvästi" + "tallentaa ja analysoida määrittämäsi ajan verran" + + tallentaa ja analysoida %s viikon ajan + tallentaa ja analysoida viikon ajan + + "Sovelluskehittäjä ei tarkentanut, miten sovellus käyttää dataasi." + - + + + + + + "Oletussovellukset" + "Ei oletussovelluksia" + "Ei sovelluksia" "Puhelin-sovellus" "Tekstiviestisovellus" "Selainsovellus" "Galleriasovellus" "Musiikkisovellus" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml index 049caf706..ba2f5736e 100644 --- a/res/values-fr-rCA/strings.xml +++ b/res/values-fr-rCA/strings.xml @@ -95,7 +95,8 @@ "Les 15 dernières minutes" "Aucune autoris. d\'utilisation" "Util. des autoris. de l\'appli" - "Il y a %1$s" + "Accès : %1$s fois. Durée totale : %2$s. Dernière utilisation : il y a %3$s." + "Accès : %1$s fois. Dernière utilisation : il y a %2$s." "Autoriser" "Autoriser tout le temps" "Autoriser uniquement lorsque l\'appli est en cours d\'utilis." @@ -103,15 +104,11 @@ "Autorisation %1$s" "Accès à %1$s pour %2$s" "%1$s a accédé à votre %2$s il y a %3$s." - - + "%1$s n\'a pas accédé à votre %2$s." "Afficher les autorisations d\'utilisation détaillées" - - - - - - + "Accès le plus récent : il y a %1$s" + "Autorisée" + "Refusé" %s jour %s jours @@ -136,36 +133,35 @@ - + "Le concepteur de l\'application a indiqué que vos données pourrait être :" + "Si vous n\'aimez pas la manière dont ce concepteur utilise vos données, vous pouvez refuser d\'accorder l\'autorisation." + "Téléversées vers le nuage" + "Téléversées vers le nuage lorsque vous l\'autorisez explicitement" + "Partagées avec les annonceurs ou les entreprises" + "Partagées avec les annonceurs ou les entreprises lorsque vous le définissez explicitement" + "Utilisée pour la monétisation" + "Utilisées pour la monétisation lorsque vous l\'autorisez explicitement" + "Enregistrées et analysées pour toujours" + "Enregistrées et analysées pour une durée que vous spécifiez" + + Enregistrées et analysées pendant %s semaine + Enregistrées et analysées pendant %s semai​nes + + "Le concepteur de l\'application n\'a pas indiqué comment celle-ci utilise vos données." + - + + + + + + "Applications par défaut" + "Aucune application par défaut" + "Aucune application" "Application Téléphone" "Application de messagerie texte" "Application de navigateur" "Application de galerie" "Application de musique" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index af807d4c4..37d03842a 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -95,7 +95,8 @@ "15 dernières minutes" "Aucune autorisation utilisée" "Utilisation des autorisations" - "Il y a %1$s" + "Accès : %1$s fois. Durée totale : %2$s. Dernière utilisation il y a %3$s." + "Accès : %1$s fois. Dernière utilisation il y a %2$s." "Autoriser" "Toujours autoriser" "Autoriser seulement quand l\'appli est en cours d\'utilisation" @@ -103,15 +104,11 @@ "Autorisation : %1$s" "L\'application %2$s est autorisée à accéder à votre/vos %1$s" "%1$s a accédé à votre/vos %2$s il y a %3$s." - - + "%1$s n\'a pas accédé à votre %2$s." "Afficher l\'utilisation détaillée des autorisations" - - - - - - + "Dernier accès il y a %1$s" + "Autorisées" + "Refusées" %s jour %s jours @@ -136,36 +133,35 @@ - + "Le développeur de l\'application signale que vos données pourront être :" + "Si la manière dont le développeur de cette application compte utiliser vos données ne vous convient pas, vous pouvez refuser l\'autorisation." + "Importées dans le cloud" + "Importées dans le cloud lorsque vous l\'autorisez de manière explicite" + "Partagées avec des annonceurs ou des entreprises" + "Partagées avec des annonceurs ou des entreprises lorsque vous l\'autorisez de manière explicite" + "Utilisées pour la monétisation" + "Utilisées pour la monétisation lorsque vous l\'autorisez de manière explicite" + "Enregistrées et analysées indéfiniment" + "Enregistrées et analysées pendant une période que vous déterminez" + + Enregistrées et analysées pendant %s semaine + Enregistrées et analysées pendant %s semaines + + "Le développeur de l\'application n\'a pas indiqué la manière dont vos données seront utilisées." + - + + + + + + "Applications par défaut" + "Aucune application par défaut" + "Aucune application" "Application Téléphone" "Application de SMS" "Application de navigateur" "Application Galerie" "Application Musique" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml index 477101e02..2f8a2dacb 100644 --- a/res/values-gl/strings.xml +++ b/res/values-gl/strings.xml @@ -95,7 +95,8 @@ "Últimos 15 minutos" "Non se utilizaron os permisos" "Uso dos permisos da aplicación" - "Hai %1$s" + "Acceso: %1$s veces. Duración total: %2$s. Utilizouse por última vez hai %3$s." + "Acceso: %1$s veces. Utilizouse por última vez hai %2$s." "Permitir" "Permitir sempre" "Permitir só cando se estea utilizando a aplicación" @@ -103,15 +104,11 @@ "Permiso de %1$s" "Permiso de %1$s para %2$s" "%1$s accedeu hai %3$s ao seguinte: %2$s." - - + "A aplicación %1$s non ten acceso a %2$s." "Consulta os detalles sobre o uso dos permisos" - - - - - - + "O último acceso foi á seguinte hora: %1$s" + "Permiso concedido" + "Permiso denegado" %s días 1 día @@ -136,36 +133,35 @@ - + "O programador da aplicación indica que os teus datos poden:" + "Se non che gusta como utiliza o programador da aplicación os teus datos, podes rexeitar o permiso." + "Cargase na nube" + "Cargarse na nube cando o permitas explicitamente" + "Compartirse cos anunciantes ou coas empresas" + "Compartirse cos anunciantes ou coas empresas cando o permitas explicitamente" + "Utilizarse para a obtención de ingresos" + "Utilizarse para a obtención de ingresos cando o permitas explicitamente" + "Gardarse e analizarse para sempre" + "Gardarse e analizarse durante o tempo que especifiques" + + Gardarse e analizarse durante %s semanas + Gardarse e analizarse durante 1 semana + + "O programador da aplicación non especificou como utiliza a aplicación os teus datos." + - + + + + + + "Aplicacións predeterminadas" + "Sen apps predeterminadas" + "Non hai aplicacións" "Aplicación de teléfono" "Aplicación de SMS" "Aplicación de navegador" "Aplicación Galería" "Aplicación Música" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml index 6d5bc2423..59a00d85f 100644 --- a/res/values-gu/strings.xml +++ b/res/values-gu/strings.xml @@ -95,7 +95,10 @@ "છેલ્લી 15 મિનિટ" "પરવાનગીનો ઉપયોગ થયો નથી" "અ‍ૅપ પરવાનગીઓનો ઉપયોગ" - "%1$s પહેલાં" + + + + "મંજૂરી આપો" "હંમેશાં મંજૂરી આપો" "માત્ર અ‍ૅપ ઉપયોગમાં હોય ત્યારે જ મંજૂરી આપો" @@ -103,15 +106,11 @@ "%1$s પરવાનગી" "%2$s માટે %1$s ઍક્સેસ" "%1$s દ્વારા તમારી %2$sને %3$s પહેલાં અ‍ૅક્સેસ કરવામાં આવી હતી." - - + "%1$sએ તમારા %2$sનો ઍક્સેસ મેળવ્યો નથી." "પરવાનગીઓનો વિગતવાર ઉપયોગ જુઓ" - - - - - - + "સૌથી તાજેતરનો ઍક્સેસ %1$s પહેલાં" + "મંજૂર" + "નકારેલ" %s દિવસ %s દિવસ @@ -136,36 +135,36 @@ - + "ઍપ ડેવલપરના કહેવા પ્રમાણે તમારો ડેટા કદાચ:" + "આ ઍપ ડેવલપર તમારા ડેટાનો જે રીતે ઉપયોગ કરતા હોય તે જો તમને ન ગમે, તો તમે પરવાનગી નકારી શકો છો." + "ક્લાઉડ પર અપલોડ કરવા માટે" + "તમે જ્યારે ચોક્કસ મંજૂરી આપો ત્યારે ક્લાઉડ પર અપલોડ કરવા માટે" + "જાહેરાતકર્તાઓ અથવા વ્યવસાયો સાથે શેર કરવા માટે" + "તમે જ્યારે ચોક્કસ મંજૂરી આપો ત્યારે જાહેરાતકર્તાઓ અથવા વ્યવસાયો સાથે શેર કરવા માટે" + "કમાણી કરવાની પ્રક્રિયામાં ઉપયોગમાં લેવા માટે" + "તમે જ્યારે ચોક્કસ મંજૂરી આપો ત્યારે કમાણી કરવાની પ્રક્રિયામાં ઉપયોગમાં લેવા માટે" + "હંમેશાં માટે ડેટા સાચવવામાં અને તેનું વિશ્લેષણ કરવા માટે" + "તમે સ્પષ્ટપણે વર્ણવેલા સમયગાળા માટે ડેટાને સાચવવાની અને વિશ્લેષણ કરવાની પરવાનગી" + + %s અઠવાડિયા માટે ડેટાને સાચવવા અને વિશ્લેષણ કરવા માટે + %s અઠવાડિયા માટે ડેટાને સાચવવા અને વિશ્લેષણ કરવા માટે + + "ઍપ તમારા ડેટાનો કઈ રીતે ઉપયોગ કરશે તે વિશે ઍપ ડેવલપરે કોઈ સ્પષ્ટતા કરી નથી." + + + + + - + + + "ડિફૉલ્ટ ઍપ" + "કોઈ ડિફૉલ્ટ ઍપ નથી" + "ફોન ઍપ" "SMS ઍપ" "બ્રાઉઝર ઍપ" "ગૅલેરી ઍપ" "મ્યુઝિક ઍપ" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml index a3269edf9..da65053b2 100644 --- a/res/values-hi/strings.xml +++ b/res/values-hi/strings.xml @@ -95,7 +95,8 @@ "पिछले 15 मिनट में" "अनुमति का इस्तेमाल नहीं हुआ" "ऐप्लिकेशन अनुमतियों इस्तेमाल" - "%1$s पहले" + "एक्सेस: %1$s बार. कुल अवधि: %2$s. आखिरी बार %3$s पहले इस्तेमाल किया गया." + "एक्सेस: %1$s बार. आखिरी बार %2$s पहले इस्तेमाल किया गया." "मंज़ूरी दें" "हमेशा मंज़ूरी दें" "तभी मंज़ूरी दें जब ऐप्लिकेशन का इस्तेमाल हो रहा हो" @@ -103,15 +104,11 @@ "%1$s अनुमति" "%2$s के लिए %1$s" "%1$s ने %3$s पहले आपकी %2$s का इस्तेमाल किया है." - - + "%1$s ने आपसे %2$s नहीं ली है." "अनुमतियों के इस्तेमाल से जुड़ी ज़्यादा जानकारी देखें" - - - - - - + "सबसे हाल में अनुमति %1$s पहले दी गई" + "अनुमति है" + "मंज़ूरी नहीं मिली" %s दिन %s दिन @@ -136,36 +133,35 @@ - + "ऐप्लिकेशन डेवलपर के हिसाब से आपका डेटा :" + "यह ऐप्लिकेशन डेवलपर आपके डेटा का जिस तरह से इस्तेमाल कर रहा है, अगर आपको वह तरीका पसंद नहीं है, तो अनुमति देने से मना कर सकते हैं." + "क्लाउड पर अपलोड किया जा सकता है" + "साफ़ तौर पर आपकी अनुमति मिलने पर, क्लाउड पर अपलोड किया जा सकता है" + "विज्ञापन करने वालों या कारोबारियों के साथ शेयर किया जा सकता है" + "साफ़ तौर पर आपकी अनुमति मिलने पर, विज्ञापन करने वालों या कारोबारियों के साथ शेयर किया जा सकता है" + "कमाई करने के लिए इस्तेमाल किया जा सकता है" + "साफ़ तौर पर आपकी अनुमति मिलने पर, कमाई किए जाने के लिए इसका इस्तेमाल किया जा सकता है" + "हमेशा के लिए सेव किया जा सकता है और आंकड़े निकाले जा सकते हैं" + "आपके बताए गए समय तक के लिए सेव किया जा सकता है और आंकड़े निकाले जा सकते हैं" + + %s हफ़्ते के लिए सेव किया जा सकता है और आंकड़े निकाले जा सकते हैं + %s हफ़्तों के लिए सेव किया जा सकता है और आंकड़े निकाले जा सकते हैं + + "ऐप्लिकेशन डेवलपर ने यह नहीं बताया कि ऐप्लिकेशन किस तरह से आपके डेटा का इस्तेमाल करता है." + - + + + + + + "डिफ़ॉल्ट ऐप्लिकेशन" + "कोई डिफ़ॉल्ट ऐप्लिकेशन नहीं." + "कोई ऐप्लिकेशन नहीं" "फ़ोन ऐप्लिकेशन" "मैसेज (एसएमएस) ऐप्लिकेशन" "ब्राउज़र ऐप्लिकेशन" "गैलरी ऐप्लिकेशन" "संगीत ऐप्लिकेशन" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml index d07ef72fd..e6b2f8bbd 100644 --- a/res/values-hr/strings.xml +++ b/res/values-hr/strings.xml @@ -96,7 +96,8 @@ "Posljednjih 15 minuta" "Nema upotreba dopuštenja" "Upotreba dopuštenja aplikacije" - "prije %1$s" + "Pristup: %1$s puta. Ukupno trajanje: %2$s. Posljednji put korišteno prije %3$s." + "Pristup: %1$s puta. Posljednji put korišteno prije %2$s." "Dopusti" "Dopusti cijelo vrijeme" "Dopusti samo dok je aplikacija u upotrebi" @@ -104,15 +105,11 @@ "Dopuštenje %1$s" "Pristup dopuštenju %1$s za aplikaciju %2$s" "Aplikacija %1$s pristupila je dopuštenju %2$s prije %3$s." - - + "Aplikacija %1$s nije pristupila vašem dopuštenju %2$s." "Pregledajte detaljnu upotrebu dopuštenja" - - - - - - + "Posljednji pristup bio je prije %1$s" + "Dopušteno" + "Odbijeno" %s dana %s dana @@ -141,36 +138,36 @@ - + "Razvojni programer aplikacije kaže da se vaši podaci mogu:" + "Ako vam se ne sviđa način na koji razvojni programer aplikacije upotrebljava vaše podatke, možete odbiti dopuštenje." + "prenositi u oblak" + "prenositi u oblak kad to izričito dopustite" + "dijeliti s oglašivačima ili tvrtkama" + "dijeliti s oglašivačima ili tvrtkama kad to izričito dopustite" + "upotrebljavati za unovčavanje" + "upotrebljavati za unovčavanje kad to izričito dopustite" + "spremati i analizirati zauvijek" + "spremati i analizirati tijekom razdoblja koje navedete" + + spremati i analizirati​ %s tjedan + spremati i analizirati​ %s tjedna + spremati i analizirati​ %s tjedana + + "Razvojni programer aplikacije nije naveo kako aplikacija upotrebljava vaše podatke." + - + + + + + + "Zadane aplikacije" + "Nema zadanih aplikacija" + "Nema aplikacija" "Aplikacija Telefon" "Aplikacija za SMS" "Aplikacija preglednika" "Aplikacija Galerija" "Aplikacija Glazba" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml index 943a72bd2..9dccfb9dc 100644 --- a/res/values-hu/strings.xml +++ b/res/values-hu/strings.xml @@ -95,7 +95,8 @@ "Elmúlt 15 perc" "Nincs engedélyhasználat" "Alkalmazásengedély-használat" - "Ennyi idővel ezelőtt: %1$s" + "Hozzáférés: %1$s alkalommal. Teljes időtartam: %2$s. Utoljára használva ennyi ideje: %3$s" + "Hozzáférés: %1$s alkalommal. Utoljára használva ennyi ideje: %2$s" "Engedélyezés" "Mindig engedélyezett" "Csak akkor engedélyezett, ha az alkalmazás használatban van" @@ -103,15 +104,11 @@ "%1$s engedély" "%1$s hozzáférés %2$s számára" "A(z) %1$s alkalmazás hozzáfért a következőhöz: %2$s (ennyi ideje: %3$s)." - - + "A(z) %1$s még nem fért hozzá a következő engedélyhez: %2$s." "Engedélyhasználat részletes adatainak megtekintése" - - - - - - + "Legutóbbi hozzáférés ennyi idővel ezelőtt: %1$s" + "Engedélyezett" + "Elutasítva" %s nap 1 nap @@ -136,36 +133,35 @@ - + "Az alkalmazás fejlesztője szerint az Ön adataival a következők történhetnek:" + "Ha nem tetszik, hogy az alkalmazás fejlesztője hogyan használja az Ön adatait, megtagadhatja az engedélyt." + "Az alkalmazás feltöltheti őket a felhőbe" + "Az alkalmazás feltöltheti őket a felhőbe az Ön kifejezett engedélyével" + "Az alkalmazás megoszthatja őket hirdetőkkel vagy vállalkozásokkal" + "Az alkalmazás megoszthatja őket hirdetőkkel vagy vállalkozásokkal az Ön kifejezett engedélyével" + "A fejlesztő bevételszerzésre használhatja őket" + "Az alkalmazás bevételszerzésre használhatja őket az Ön kifejezett engedélyével" + "Az alkalmazás örökre mentheti és elemezheti őket" + "Az alkalmazás menti és elemzi őket az Ön által megadott ideig" + + Az alkalmazás menti és elemzi őket %s hétig + Az alkalmazás menti és elemzi őket 1 hétig + + "Az alkalmazás fejlesztője nem adta meg, hogy az alkalmazás hogyan használja a felhasználók adatait." + - + + + + + + "Alapértelmezett alkalmazások" + "Nincsenek alapértelmezettek" + "Nincsenek alkalmazások" "Telefon alkalmazás" "SMS-küldő" "Böngésző" "Galériaalkalmazás" "Zenealkalmazás" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml index 6f9b14e5f..496dbc525 100644 --- a/res/values-hy/strings.xml +++ b/res/values-hy/strings.xml @@ -95,7 +95,8 @@ "Վերջին 15 րոպեում" "Թույլտվություններ չեն կիրառվել" "Թույլտվությունների օգտագործում" - "%1$s առաջ" + "Օգտագործվել է %1$s անգամ։ Ընդհանուր տևողությունը՝ %2$s։ Վերջին անգամ օգտագործվել է %3$s առաջ։" + "Օգտագործվել է %1$s անգամ։ Վերջինը՝ %2$s առաջ։" "Թույլատրել" "Թույլատրել միշտ" "Թույլատրել, միայն երբ հավելվածն օգտագործվում է" @@ -103,15 +104,11 @@ %1$s» թույլտվություն" %1$s» թույլտվության տրամադրում %2$s հավելվածին" "%1$s հավելվածը ստացել է «%2$s» թույլտվությունը %3$s առաջ:" - - + "%1$s հավելվածին հասանելի չէ ձեր %2$sը:" "Դիտել թույլտվությունների օգտագործման մանրամասները" - - - - - - + "Վերջին մուտքը՝ %1$s առաջ" + "Թույլատրված" + "Մերժված" %s օր %s օր @@ -136,36 +133,35 @@ - + "Հավելվածի մշակողն ասում է, որ ձեր տվյալները կարող են՝" + "Եթե ձեզ դուր չի գալիս, թե ինչպես է հավելվածի մշակողն օգտագործում ձեր տվյալները, դուք կարող եք հեռացնել թույլտվությունը:" + "Վերբեռնվել ամպ" + "Վերբեռնվել ամպ, երբ դա դուք բացահայտ թույլատրում եք" + "Տրամադրվել գովազդատուներին կամ ընկերություններին" + "Տրամադրվել գովազդատուներին կամ ընկերություններին, երբ դա դուք բացահայտ թույլատրում եք" + "Օգտագործվել դրամայնացման համար" + "Օգտագործվել դրամայնացման համար, երբ դա դուք բացահայտ թույլատրում եք" + "Պահվել և վերլուծվել ընդմիշտ" + "Պահվել և վերլուծվել այնքան ժամանակ, որքան դուք կնշեք" + + Պահվել և վերլուծվել %s շաբաթ + Պահվել և վերլուծվել %s շաբաթ + + "Հավելվածի մշակողը չի նշել, թե ինչպես է հավելվածը օգտագործում ձեր տվյալները:" + - + + + + + + "Կանխադրված հավելվածներ" + "Կանխադրված հավելվածներ չկան" + "Հավելվածներ չկան" "«Հեռախոս» հավելված" "«SMS» հավելված" "«Դիտարկիչ» հավելված" "Ցուցասրահ" "Երաժշտություն" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml index e81856911..68c730f3b 100644 --- a/res/values-in/strings.xml +++ b/res/values-in/strings.xml @@ -95,7 +95,8 @@ "15 menit terakhir" "Tidak ada penggunaan izin" "Penggunaan izin aplikasi" - "%1$s yang lalu" + "Akses: %1$s kali. Durasi total: %2$s. Terakhir digunakan %3$s yang lalu." + "Akses: %1$s kali. Terakhir digunakan %2$s yang lalu." "Izinkan" "Izinkan sepanjang waktu" "Izinkan hanya saat aplikasi sedang digunakan" @@ -103,15 +104,11 @@ "Izin %1$s" "Akses %1$s untuk %2$s" "%1$s mengakses %2$s Anda %3$s yang lalu." - - + "%1$s belum mengakses %2$s Anda." "Melihat penggunaan izin mendetail" - - - - - - + "Akses terbaru %1$s yang lalu" + "Diizinkan" + "Ditolak" %s hari 1 hari @@ -136,36 +133,35 @@ - + "Developer aplikasi mengatakan data Anda dapat:" + "Jika tidak menyukai cara developer aplikasi ini menggunakan data Anda, Anda dapat menolak izin." + "Diupload ke cloud" + "Diupload ke cloud jika Anda secara tegas mengizinkannya" + "Dibagikan kepada pengiklan atau bisnis" + "Dibagikan kepada pengiklan atau bisnis jika Anda secara tegas mengizinkannya" + "Digunakan untuk monetisasi" + "Digunakan untuk monetisasi jika Anda secara tegas mengizinkannya" + "Disimpan dan dianalisis selamanya" + "Disimpan dan dianalisis selama durasi yang Anda tentukan" + + Disimpan dan dianalisis selama %s minggu + Disimpan dan dianalisis selama 1 minggu + + "Developer aplikasi tidak menentukan bagaimana aplikasi ini menggunakan data Anda." + - + + + + + + "Aplikasi default" + "Tidak ada aplikasi default" + "Tidak ada aplikasi" "Aplikasi telepon" "Aplikasi SMS" "Aplikasi browser" "Aplikasi Galeri" "Aplikasi Musik" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml index ca7f87b37..fa08d2ffe 100644 --- a/res/values-is/strings.xml +++ b/res/values-is/strings.xml @@ -95,7 +95,8 @@ "Síðustu 15 mínútur" "Engin heimildanotkun" "Notkun heimilda forrits" - "fyrir %1$s" + "Aðgangur: %1$s sinnum. Heildarlengd: %2$s. Síðast notað fyrir %3$s." + "Aðgangur: %1$s sinnum. Síðast notað fyrir %2$s." "Leyfa" "Leyfa alltaf" "Leyfa aðeins þegar forritið er í notkun" @@ -103,15 +104,11 @@ "%1$s heimild" "%1$s aðgangur að %2$s" "%1$s fékk aðgang að %2$s þínu fyrir %3$s." - - + "%1$s hefur ekki fengið aðgang að %2$s." "Skoða nákvæma heimildanotkun" - - - - - - + "Nýlegasti aðgangur fyrir %1$s" + "Leyft" + "Hafnað" %s dagur %s dagar @@ -136,36 +133,35 @@ - + "Þróunaraðili forrits segir að gögnin þín kunni að vera:" + "Ef þér líkar ekki hvernig þessi þróunaraðili forrits notar gögnin þín geturðu hafnað heimildinni." + "Hlaðið inn á skýið" + "Hlaðið inn á skýið þegar þú leyfir það sérstaklega" + "Deilt með auglýsendum eða fyrirtækjum" + "Deilt með auglýsendum eða fyrirtækjum þegar þú leyfir það sérstaklega" + "Notað fyrir tekjuöflun" + "Notað fyrir tekjuöflun þegar þú leyfir það sérstaklega" + "Vistað og greint til frambúðar" + "Vistað og greint í ákveðinn tíma sem þú tilgreindir" + + Vistað og greint í %s viku + Vistað og greint í %s vikur + + "Þróunaraðili forrits tilgreindi ekki hvernig forritið notar gögnin þín." + - + + + + + + "Sjálfgefin forrit" + "Engin sjálfgefin forrit" + "Engin forrit" "Símaforrit" "SMS-forrit" "Vafraforrit" "Myndasafnsforrit" "Tónlistarforrit" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml index 31e6a21e1..5a1610f51 100644 --- a/res/values-it/strings.xml +++ b/res/values-it/strings.xml @@ -95,7 +95,8 @@ "Ultimi 15 minuti" "Autorizzazioni non usate" "Uso delle autorizzazioni app" - "%1$s fa" + "Accesso: %1$s volte. Durata totale: %2$s. Ultimo utilizzo: %3$s fa." + "Accesso: %1$s volte. Ultimo utilizzo: %2$s fa." "Consenti" "Consenti sempre" "Consenti solo mentre l\'app è in uso" @@ -103,15 +104,11 @@ "Autorizzazione per i dati di %1$s" "Accesso ai dati di %1$s per l\'app %2$s" "L\'app %1$s ha avuto accesso ai tuoi dati di %2$s %3$s fa." - - + "%1$s non ha accesso a %2$s." "Consulta l\'uso dettagliato delle autorizzazioni" - - - - - - + "Ultimo accesso: %1$s fa" + "Consentite" + "Rifiutate" %s giorni 1 giorno @@ -136,36 +133,35 @@ - + "Lo sviluppatore dell\'app dichiara che i tuoi dati potrebbero essere:" + "Se non gradisci il modo in cui lo sviluppatore dell\'app usa i tuoi dati, puoi negare l\'autorizzazione." + "Caricati sulla cloud" + "Caricati sulla cloud con la tua autorizzazione esplicita" + "Condivisi con inserzionisti o attività" + "Condivisi con inserzionisti o attività con la tua autorizzazione esplicita" + "Usati per la monetizzazione" + "Usati per la monetizzazione con la tua autorizzazione esplicita" + "Memorizzati e analizzati per sempre" + "Memorizzati e analizzati per la durata di tempo da te specificata" + + Memorizzati e analizzati per %s settimane + Memorizzati e analizzati per 1 settimana + + "Lo sviluppatore dell\'app non ha indicato la modalità di utilizzo dei tuoi dati nell\'app." + - + + + + + + "App predefinite" + "Nessuna app predefinita" + "Nessuna app" "App Telefono" "App per SMS" "App browser" "App Galleria" "App per la musica" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml index 9d2de55b5..4f93b6e14 100644 --- a/res/values-iw/strings.xml +++ b/res/values-iw/strings.xml @@ -97,7 +97,8 @@ "15 הדקות האחרונות" "אין שימוש בהרשאות" "שימוש בהרשאות האפליקציה" - "לפני %1$s" + "גישה: %1$s פעמים. משך זמן כולל: %2$s. שימוש אחרון לפני %3$s." + "גישה: %1$s פעמים. שימוש אחרון לפני %2$s." "לאישור" "לאישור כל הזמן" "לאישור רק בזמן שהאפליקציה בשימוש" @@ -105,15 +106,11 @@ "הרשאה ל%1$s" "גישה ל%1$s עבור %2$s" "נעשתה גישה ל%2$s על ידי %1$s לפני %3$s." - - + "לאפליקציה %1$s לא הייתה גישה אל %2$s." "הצגת שימוש מפורט בהרשאות" - - - - - - + "הגישה האחרונה הייתה לפני %1$s" + "יש הרשאה" + "אין הרשאה" יומיים (%s) %s ימים @@ -146,36 +143,37 @@ - + "מפתח האפליקציה אומר שייתכן שהנתונים שלך:" + "אם אופן השימוש של מפתח האפליקציה בנתונים שלך לא מקובל עליך, ניתן להימנע ממתן ההרשאה." + "יועלו לענן" + "יועלו לענן כשיתקבל ממך אישור מפורש לכך" + "ישותפו עם מפרסמים או עסקים" + "ישותפו עם מפרסמים או עסקים כשיתקבל ממך אישור מפורש לכך" + "ישמשו למונטיזציה" + "ישמשו למונטיזציה כשיתקבל ממך אישור מפורש לכך" + "יישמרו וינותחו לנצח" + "יישמרו וינותחו למשך הזמן שיצוין" + + יישמרו וינותחו למשך %s שבועות + יישמרו וינותחו למשך %s שבועות + יישמרו וינותחו למשך %s שבועות + יישמרו וינותחו למשך שבוע אחד + + "מפתח האפליקציה לא ציין איזה שימוש נעשה בנתונים שלך על ידי האפליקציה." + - + + + + + + "אפליקציות ברירת מחדל" + "אין אפליקציות ברירת מחדל" + "אין אפליקציות" "אפליקציית \'טלפון\'" "‏אפליקציית SMS" "אפליקציית דפדפן" "גלריית האפליקציות" "אפליקציית מוזיקה" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml index a043d4b6a..c39ad0311 100644 --- a/res/values-ja/strings.xml +++ b/res/values-ja/strings.xml @@ -95,7 +95,8 @@ "過去 15 分間" "権限の使用はなし" "アプリの権限の使用" - "%1$s 前" + "アクセス: %1$s 回。合計時間: %2$s。前回の使用: %3$s前。" + "アクセス: %1$s 回。前回の使用: %2$s前。" "許可" "常に許可" "アプリが使用中の場合のみ許可" @@ -103,15 +104,11 @@ "%1$sの権限" "%2$s%1$sへのアクセス権" "%1$s%3$s前に%2$sにアクセスしました。" - - + "%1$s はユーザーの%2$sにはアクセスしていません。" "権限の使用に関する詳細を表示" - - - - - - + "最終アクセスは %1$s前です" + "許可" + "拒否" %s 1日 @@ -136,36 +133,35 @@ - + "アプリのデベロッパーは、以下の方法でユーザーデータを使用する可能性があります。" + "このアプリのデベロッパーにユーザーデータの使用を許可したくない場合は拒否してください。" + "クラウドにアップロードする" + "明示的に許可するとデータがクラウドにアップロードされます" + "広告主や企業に提供する" + "明示的に許可するとデータが広告主や企業に提供されます" + "収益化に使用する" + "明示的に許可するとデータが収益化に使用されます" + "保存と分析を無期限で行う" + "保存と分析を、ユーザーが指定した期間行う" + + 保存と分析を %s 週間行う + 保存と分析を 1 週間行う + + "アプリのデベロッパーは、ユーザーデータをどのように使用するかを明確にしていません。" + - + + + + + + "デフォルトのアプリ" + "デフォルトのアプリはありません" + "アプリなし" "電話アプリ" "SMS アプリ" "ブラウザアプリ" "ギャラリー アプリ" "音楽アプリ" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml index 830940eb6..9d9690cf4 100644 --- a/res/values-ka/strings.xml +++ b/res/values-ka/strings.xml @@ -95,7 +95,8 @@ "ბოლო 15 წუთი" "ამ ნებართვებს აპები არ იყენებს" "აპის ნებართვებით სარგებლობა" - "%1$sს წინ" + "წვდომა: %1$s-ჯერ. საერთო ხანგრძლივობა: %2$s. ბოლო გამოყენებიდან გავიდა %3$s." + "წვდომა: %1$s-ჯერ. ბოლო გამოყენებიდან გავიდა %2$s." "დაშვება" "ყოველთვის დაშვება" "მხოლოდ აპის გამოყენებისას დაშვება" @@ -103,15 +104,11 @@ "ნებართვა: %1$s" "%1$s: წვდომა %2$s-ისთვის" "%1$s-მა გამოიყენა თქვენი %2$s %3$sს წინ." - - + "%1$s-ს არ გამოუყენებია თქვენი %2$s." "ნებართვების გამოყენების დეტალურად ნახვა" - - - - - - + "ბოლო წვდომიდან გავიდა %1$s" + "დაშვებულია" + "უარყოფილია" %s დღე 1 დღე @@ -136,36 +133,35 @@ - + "აპის დეველოპერის თქმით, თქვენი მონაცემები:" + "თუ აპის დეველოპერის მიერ თქვენი მონაცემების გამოყენების ხერხი არ მოგწონთ, შეგიძლიათ უარყოთ ნებართვა." + "აიტვირთება ღრუბელში" + "აიტვირთება ღრუბელში, თუ ეს საგანგებოდ არის დაშვებული თქვენ მიერ" + "ზიარდება რეკლამის განმთავსებლებთან ან დაწესებულებებთან" + "ზიარდება რეკლამის განმთავსებლებთან ან დაწესებულებებთან, თუ ეს საგანგებოდ არის დაშვებული თქვენ მიერ" + "გამოიყენება მონეტიზაციისთვის" + "გამოიყენება მონეტიზაციისთვის, თუ ეს საგანგებოდ არის დაშვებული თქვენ მიერ" + "შეინახება და გაანალიზდება სამუდამოდ" + "შეინახება და გაანალიზდება თქვენ მიერ მითითებული პერიოდის განმავლობაში" + + შეინახება და გაანალიზდება %s კვირის განმავლობაში + შეინახება და გაანალიზდება 1 კვირის განმავლობაში + + "აპის დეველოპერს არ მიუთითებია, როგორ მოხდება აპის მიერ თქვენი მონაცემების გამოყენება." + - + + + + + + "ნაგულისხმევი აპები" + "ნაგულისხმევი აპები არ არის" + "აპები არ არის" "ტელეფონის აპი" "SMS აპი" "ბრაუზერის აპი" "გალერეის აპი" "მუსიკის აპი" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml index 9fcb69e39..edb128bab 100644 --- a/res/values-kk/strings.xml +++ b/res/values-kk/strings.xml @@ -95,7 +95,8 @@ "Соңғы 15 минут" "Рұқсаттар пайдаланылмаған" "Қолданба рұқсаттарын пайдалану" - "%1$s бұрын" + "Кіру рұқсаты сұралды: %1$s рет. Жалпы ұзақтығы: %2$s. Соңғы рет %3$s бұрын пайдаланылған." + "Кіру рұқсаты сұралды: %1$s рет. Соңғы рет %2$s бұрын пайдаланылған." "Рұқсат беру" "Әрдайым рұқсат беру" "Қолданба пайдаланылып жатқанда ғана рұқсат беру" @@ -103,15 +104,11 @@ "%1$s рұқсаты" "%2$s қолданбасына арналған %1$s рұқсатына кіру" "%1$s қолданбасы %2$s рұқсатына %3$s бұрын кірді." - - + "%1$s қолданбасы %2$s рұқсатын пайдаланбады." "Рұқсаттардың пайдаланылуы туралы мәліметтерді көру" - - - - - - + "Соңғы пайдаланылған уақыты: %1$s бұрын" + "Берілген рұқсаттар" + "Тыйым салынғандар" %s күн 1 күн @@ -136,36 +133,35 @@ - + "Қолданба әзірлеушісі көрсеткендей, деректеріңіз келесідей болуы мүмкін:" + "Егер қолданба әзірлеушісінің деректерді пайдалану әдісі ұнамаса, рұқсат бермеуіңізге болады." + "Бұлтқа жүктеп салынады" + "Айқын рұқсат берілген кезде, бұлтқа жүктеп салынады" + "Жарнама берушілермен немесе компаниялармен бөлісіледі" + "Айқын рұқсат берілген кезде, жарнама берушілермен немесе компаниялармен бөлісіледі" + "Монетизация үшін пайдаланылады" + "Айқын рұқсат берілген кезде, монетизация үшін пайдаланылады" + "Шексіз уақытқа сақталады және талданады" + "Сіз көрсеткен мерзім бойы сақталады және талданады" + + %s аптаға сақталады және талданады + 1 аптаға сақталады және талданады + + "Қолданба әзірлеушісі қолданбаның деректерді қалай пайдаланатынын көрсетпеген." + - + + + + + + "Әдепкі қолданбалар" + "Әдепкі қолданбалар жоқ" + "Қолданбалар жоқ" "Телефон қолданбасы" "SMS қолданбасы" "Браузер қолданбасы" "Галерея қолданбасы" "Музыка қолданбасы" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml index 7963e5471..be1c210f6 100644 --- a/res/values-km/strings.xml +++ b/res/values-km/strings.xml @@ -95,7 +95,8 @@ "15 នាទី​ចុងក្រោយ" "គ្មាន​ការប្រើប្រាស់​ការអនុញ្ញាត​ទេ" "ការប្រើប្រាស់​ការអនុញ្ញាត​កម្មវិធី" - "%1$s មុន" + "ចូលប្រើ៖ %1$s ដង។ រយៈពេល​សរុប៖ %2$s។ បានប្រើចុងក្រោយ %3$s មុន។" + "ចូលប្រើ៖ %1$s ដង។ បានប្រើចុងក្រោយ %2$s មុន។" "អនុញ្ញាត" "អនុញ្ញាតគ្រប់ពេល" "អនុញ្ញាត​ពេល​កំពុង​ប្រើប្រាស់​កម្មវិធីតែ​ប៉ុណ្ណោះ" @@ -103,15 +104,11 @@ "ការអនុញ្ញាត %1$s" "ការចូលប្រើ %1$s សម្រាប់ %2$s" "%1$s បាន​ចូលប្រើ %2$s របស់អ្នកកាលពី %3$s មុន។" - - + "%1$s មិន​បាន​ចូលប្រើ %2$s របស់អ្នក​ទេ។" "មើល​ការ​ប្រើប្រាស់​ការអនុញ្ញាត​លម្អិត" - - - - - - + "ការចូល​ប្រើ​​ចុងក្រោយបំផុត %1$s មុន" + "បាន​អនុញ្ញាត" + "បានបដិសេធ" %s ថ្ងៃ 1 ថ្ងៃ @@ -136,36 +133,35 @@ - + "អ្នក​អភិវឌ្ឍន៍​កម្មវិធី​និយាយ​ថា ទិន្នន័យរបស់អ្នក​អាច៖" + "ប្រសិនបើអ្នក​មិន​ពេញ​ចិត្ត​នឹងរបៀបដែល​អ្នក​អភិវឌ្ឍន៍​កម្មវិធី​កំពុង​ប្រើប្រាស់​ទិន្នន័យ​របស់អ្នក អ្នក​អាច​បដិសេធ​មិនឱ្យចូលប្រើ។" + "​បង្ហោះ​ទៅក្នុង​ពពក" + "បង្ហោះ​ទៅក្នុង​ពពក នៅពេល​អ្នក​អនុញ្ញាត​ច្បាស់​លាស់" + "​ចែករំលែក​ជាមួយ​អ្នកផ្សាយពាណិជ្ជកម្ម ឬ​អាជីវកម្ម​ផ្សេងៗ" + "​ចែករំលែក​ជាមួយ​អ្នកផ្សាយពាណិជ្ជកម្ម ឬ​អាជីវកម្ម​ផ្សេងៗ នៅពេល​អ្នក​អនុញ្ញាត​ច្បាស់​លាស់" + "​ប្រើ​សម្រាប់​រកប្រាក់" + "ប្រើ​សម្រាប់​រកប្រាក់ នៅពេល​អ្នក​អនុញ្ញាត​ច្បាស់​លាស់" + "​រក្សា​ទុក និង​វិភាគ​ជារៀងរហូត" + "​រក្សាទុក និងវិភាគ​ក្នុងរយៈពេលដែលអ្នកបញ្ជាក់" + + ​រក្សាទុក និងវិភាគ​រយៈពេល %s សប្តាហ៍ + រក្សាទុក និងវិភាគ​រយៈពេល​ 1 សប្តាហ៍ + + "អ្នក​អភិវឌ្ឍន៍​កម្មវិធី​មិន​បាន​បញ្ជាក់ថា កម្មវិធី​ប្រើប្រាស់​ទិន្នន័យ​របស់អ្នករបៀប​ណា​ទេ។" + - + + + + + + "កម្មវិធី​លំនាំដើម" + "គ្មានកម្មវិធីលំនាំដើមទេ" + "គ្មានកម្មវិធី​ទេ​" "កម្មវិធីទូរសព្ទ" "កម្មវិធីផ្ញើសារ SMS" "កម្មវិធីរុករកតាមអ៊ីនធឺណិត" "កម្មវិធីសាល​រូបភាព" "កម្មវិធី​តន្រី្ត" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml index c0bc099bd..6969f005b 100644 --- a/res/values-kn/strings.xml +++ b/res/values-kn/strings.xml @@ -95,7 +95,10 @@ "ಹಿಂದಿನ 15 ನಿಮಿಷಗಳು" "ಅನುಮತಿಯ ಬಳಕೆಗಳು ಇಲ್ಲ" "ಆ್ಯಪ್‌ ಅನುಮತಿಗಳ ಬಳಕೆ" - "%1$s ನಿಮಿಷಗಳ ಹಿಂದೆ" + + + + "ಅನುಮತಿಸಿ" "ಎಲ್ಲಾ ಸಮಯದಲ್ಲೂ ಅನುಮತಿಸಿ" "ಆ್ಯಪ್ ಬಳಕೆಯಲ್ಲಿದ್ದಾಗ ಮಾತ್ರ ಅನುಮತಿಸಿ" @@ -103,15 +106,11 @@ "%1$s ಅನುಮತಿ" "%2$s ಆ್ಯಪ್‌ಗಾಗಿ %1$s ಪ್ರವೇಶ" "%1$s ಆ್ಯಪ್ ನಿಮ್ಮ %2$s ಅನ್ನು %3$s ಹಿಂದೆ ಪ್ರವೇಶಿಸಿದೆ." - - + "%1$s ನಿಮ್ಮ %2$s ಅನ್ನು ಪ್ರವೇಶಿಸಿಲ್ಲ." "ವಿವರವಾದ ಅನುಮತಿಗಳ ಬಳಕೆಯನ್ನು ವೀಕ್ಷಿಸಿ" - - - - - - + "%1$s ಹಿಂದೆ ತೀರಾ ಇತ್ತೀಚಿನ ಪ್ರವೇಶವಾಗಿದೆ" + "ಅನುಮತಿಸಲಾಗಿದೆ" + "ನಿರಾಕರಿಸಲಾಗಿದೆ" %s ದಿನಗಳು %s ದಿನಗಳು @@ -136,36 +135,36 @@ - + "ಆ್ಯಪ್ ಡೆವಲಪರ್ ಈ ರೀತಿಯಾಗಿ ಹೇಳುತ್ತಾರೆ ನಿಮ್ಮ ಡೇಟಾ ಈ ರೀತಿಯಾಗಿರಬಹುದು:" + "ಈ ಆ್ಯಪ್ ಡೆವಲಪರ್, ನಿಮ್ಮ ಡೇಟಾವನ್ನು ಬಳಸುವ ರೀತಿಯು ನಿಮಗೆ ಇಷ್ಟವಾಗದಿದ್ದಲ್ಲಿ, ನೀವು ಅನುಮತಿಯನ್ನು ನಿರಾಕರಿಸಬಹುದು." + "ಕ್ಲೌಡ್‌ಗೆ ಅಪ್‌ಲೋಡ್ ಮಾಡಲಾಗಿದೆ" + "ಡೇಟಾ ಅಪ್‌ಲೋಡ್ ಮಾಡುವುದನ್ನು ನೀವು ಸ್ಪಷ್ಟವಾಗಿ ಅನುಮತಿಸಿದಾಗ, ಇದನ್ನು ಕ್ಲೌಡ್‌ಗೆ ಅಪ್‌ಲೋಡ್ ಮಾಡಲಾಗಿದೆ" + "ಜಾಹೀರಾತುದಾರರು ಅಥವಾ ವ್ಯಾಪಾರಗಳ ಜೊತೆಗೆ ಹಂಚಿಕೊಳ್ಳಲಾಗಿದೆ" + "ಡೇಟಾ ಹಂಚಿಕೊಳ್ಳುವುದನ್ನು ನೀವು ಸ್ಪಷ್ಟವಾಗಿ ಅನುಮತಿಸಿದಾಗ, ಇದನ್ನು ಜಾಹೀರಾತುದಾರರು ಅಥವಾ ವ್ಯಾಪಾರಗಳ ಜೊತೆಗೆ ಹಂಚಿಕೊಳ್ಳಲಾಗಿದೆ" + "ಹಣ ಗಳಿಕೆಗಾಗಿ ಬಳಸಲಾಗಿದೆ" + "ಡೇಟಾ ಬಳಸುವುದನ್ನು ನೀವು ಸ್ಪಷ್ಟವಾಗಿ ಅನುಮತಿಸಿದಾಗ, ಇದನ್ನು ಹಣ ಗಳಿಕೆಗಾಗಿ ಬಳಸಲಾಗಿದೆ" + "ಶಾಶ್ವತವಾಗಿ ಉಳಿಸಲಾಗಿದೆ ಮತ್ತು ವಿಶ್ಲೇಷಿಸಲಾಗಿದೆ" + "ನೀವು ನಿರ್ದಿಷ್ಟಪಡಿಸಿದ ಅವಧಿಗಾಗಿ ಉಳಿಸಲಾಗಿದೆ ಮತ್ತು ವಿಶ್ಲೇಷಿಸಲಾಗಿದೆ" + + %s ವಾರಗಳವರೆಗೆ ಉಳಿಸಲಾಗಿದೆ ಮತ್ತು ವಿಶ್ಲೇಷಿಸಲಾಗಿದೆ + %s ವಾರಗಳವರೆಗೆ ಉಳಿಸಲಾಗಿದೆ ಮತ್ತು ವಿಶ್ಲೇಷಿಸಲಾಗಿದೆ + + "ಆ್ಯಪ್ ಹೇಗೆ ನಿಮ್ಮ ಡೇಟಾವನ್ನು ಬಳಸುತ್ತದೆ ಎಂಬುದನ್ನು ಆ್ಯಪ್ ಡೆವಲಪರ್ ನಿರ್ದಿಷ್ಟಪಡಿಸಿಲ್ಲ." + + + + + - + + + "ಡೀಫಾಲ್ಟ್ ಆ್ಯಪ್‌ಗಳು" + "ಯಾವುದೇ ಡೀಫಾಲ್ಟ್‌ ಆ್ಯಪ್‌ಗಳಿಲ್ಲ" + "ಫೋನ್ ಆ್ಯಪ್" "ಎಸ್ಎಂಎಸ್ ಆ್ಯಪ್" "ಬ್ರೌಸರ್ ಆ್ಯಪ್" "ಗ್ಯಾಲರಿ ಆ್ಯಪ್‌" "ಸಂಗೀತ ಆ್ಯಪ್‌" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml index 3720f2d17..9ed59923c 100644 --- a/res/values-ko/strings.xml +++ b/res/values-ko/strings.xml @@ -95,7 +95,8 @@ "지난 15분" "사용 권한 없음" "앱 권한 사용" - "%1$s 전" + "액세스: %1$s회, 총 기간: %2$s, 마지막 사용: %3$s 전" + "액세스: %1$s회, 마지막 사용: %2$s 전" "허용" "항상 허용" "앱 사용 중에만 허용" @@ -103,15 +104,11 @@ "%1$s 권한" "%2$s%1$s 액세스 권한" "%3$s 전에 %1$s 앱이 %2$s에 액세스했습니다." - - + "%1$s 앱이 %2$s에 액세스하지 않았습니다." "자세한 권한 사용 내역 보기" - - - - - - + "최근 액세스: %1$s 전" + "허용됨" + "거부됨" %s 1일 @@ -136,36 +133,35 @@ - + "앱 개발자에 따르면 데이터가 다음과 같이 사용될 수 있습니다" + "앱 개발자의 데이터 사용 방식이 마음에 들지 않으면 권한 요청을 거부할 수 있습니다." + "클라우드에 업로드됨" + "사용자가 명시적으로 허용할 경우 클라우드에 업로드됨" + "광고주 또는 비즈니스와 공유됨" + "사용자가 명시적으로 허용할 경우 광고주 또는 비즈니스와 공유됨" + "수익 창출에 사용됨" + "사용자가 명시적으로 허용할 경우 수익 창출에 사용됨" + "영구적으로 저장 및 분석됨" + "사용자가 지정한 기간 동안 저장 및 분석됨" + + %s주 동안 저장 및 분석됨 + 1주 동안 저장 및 분석됨 + + "앱 개발자가 앱의 데이터 사용 방식을 명시하지 않았습니다." + - + + + + + + "기본 앱" + "기본 앱 없음" + "앱 없음" "전화 앱" "SMS 앱" "브라우저 앱" "갤러리 앱" "음악 앱" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml index 4b9b32079..a67a5db11 100644 --- a/res/values-ky/strings.xml +++ b/res/values-ky/strings.xml @@ -95,7 +95,8 @@ "Акыркы 15 мүнөттө" "Уруксаттар колдонулган жок" "Колдонмонун уруксаттарын пайдалануу" - "%1$s мурун" + "Кирүү: %1$s жолу. Жалпы колдонулган убакыт: %2$s. Акыркы жолу %3$s колдонулган." + "Кирүү: %1$s жолу. Акыркы жолу %2$s колдонулган." "Уруксат берүү" "Бардык учурда уруксат берүү" "Колдонмо пайдаланылып жаткан учурда гана уруксат берүү" @@ -103,15 +104,11 @@ "%1$s дайындарына уруксаттар" "%2$s үчүн %1$s дайындарына кирүү" "%1$s %2$s дайындарыңызга %3$s мурун кирген." - - + "%1$s %2$s уруксаттарыңызга кирген жок." "Уруксаттардын колдонулушун чоо-жайы менен көрүү" - - - - - - + "Эң акыркы жолу %1$s мурун кирген" + "Уруксат берилген" + "Четке кагылды" %s күн 1 күн @@ -136,36 +133,35 @@ - + "Колдонмону иштеп чыгуучулардын айтышы боюнча, дайындарыңыз төмөнкүдөй болушу мүмкүн:" + "Бул колдонмону иштеп чыгуучунун дайындарыңызды кандайча колдонгонун жактырбасаңыз, уруксаттардан баш тартсаңыз болот." + "Булутка жүктөлүп берилет" + "Уруксат берсеңиз, булутка жүктөлүп берилет" + "Жарнамачылар жана компаниялар менен бөлүшүлөт" + "Уруксат берсеңиз, жарнамачылар жана компаниялар менен бөлүшүлөт" + "Акча табуу үчүн колдонулат" + "Сиз уруксат бергенде, акча табууга колдонулат" + "Түбөлүккө сакталат жана талдалат" + "Сиз көрсөткөн узактыкка сакталган жана талдалган" + + %s аптага сакталып, талдалат + 1 аптага сакталып, талдалат + + "Колдонмону иштеп чыгуучу колдонмо дайындарыңызды кандайча колдонгонун көрсөткөн жок." + - + + + + + + "Демейки колдонмолор" + "Демейки колдонмолор жок" + "Бир да колдонмо жок" "¨Телефон\" колдонмосу" "\"SMS\" колдонмосу" "\"Серепчи\" колдонмосу" "Галерея колдонмосу" "Музыка колдонмосу" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-lo/strings.xml b/res/values-lo/strings.xml index 35ac1225a..a51f58a2b 100644 --- a/res/values-lo/strings.xml +++ b/res/values-lo/strings.xml @@ -95,7 +95,8 @@ "15 ນາທີຜ່ານມາ" "ບໍ່ມີການນຳໃຊ້ສິດອະນຸຍາດ" "ການໃຊ້ສິດອະນຸຍາດແອັບ" - "%1$s ກ່ອນ" + "ເຂົ້າເຖິງ: %1$s ເທື່ອ. ໄລຍະເວລາທັງຮວມ: %2$s. ໃຊ້ຫຼ້າສຸດ %3$s ກ່ອນ." + "ເຂົ້າເຖິງ: %1$s ເທື່ອ. ໃຊ້ຫຼ້າສຸດ %2$s ກ່ອນ." "ອະນຸຍາດ" "ອະນຸຍາດຕະຫຼອດເວລາ" "ອະນຸຍາດສະເພາະເມື່ອມີການໃຊ້ແອັບ" @@ -103,15 +104,11 @@ "ສິດອະນຸຍາດ %1$s" "ການເຂົ້າເຖິງ %1$s ສຳລັບ %2$s" "%1$s ເຂົ້າເຖິງ %2$s ຂອງທ່ານເມື່ອ %3$sກ່ອນ." - - + "%1$s ບໍ່ໄດ້ເຂົ້າເຖິງ %2$s ຂອງທ່ານ." "ເບິ່ງການໃຊ້ສິດອະນຸຍາດແບບລະອຽດ" - - - - - - + "ເຂົ້າເຖິງຫຼ້າສຸດ %1$s ກ່ອນ" + "ອະນຸຍາດແລ້ວ" + "ຖືກປະຕິເສດ" %s ມື້ 1 ມື້ @@ -136,36 +133,35 @@ - + "ຜູ້ພັດທະນາແອັບບອກວ່າຂໍ້ມູນຂອງທ່ານອາດຈະ:" + "ຫາກທ່ານບໍ່ຮູ້ວ່າຜູ້ພັດທະນາແອັບນີ້ໃຊ້ຂໍ້ມູນຂອງທ່ານແນວໃດ, ທ່ານສາມາດປະຕິເສດສິດອະນຸຍາດໄດ້." + "ອັບໂຫລດໄປໃສ່ຄລາວແລ້ວ" + "ອັບໂຫລດໄປໃສ່ຄລາວເມື່ອທ່ານອະນຸຍາດມັນຢ່າງຊັດເຈນ" + "ແບ່ງປັນກັບຜູ້ລົງໂຄສະນາ ຫຼື ທຸລະກິດຕ່າງໆ" + "ແບ່ງປັນກັບຜູ້ລົງໂຄສະນາ ຫຼື ທຸລະກິດຕ່າງໆເມື່ອທ່ານອະນຸຍາດຢ່າງຊັດເຈນ" + "ໃຊ້ສຳລັບການສ້າງລາຍໄດ້" + "ໃຊ້ສຳລັບການສ້າງລາຍໄດ້ເມື່ອທ່ານອະນຸຍາດຢ່າງຊັດເຈນ" + "ບັນທຶກ ແລະ ວິເຄາະຕະຫຼອດໄປ" + "ບັນທຶກ ແລະ ວິເຄາະເປັນໄລຍະເວລາທີ່ທ່ານລະບຸໄວ້" + + ບັນທຶກ ແລະ ວິເຄາະເປັນເວລາ %s ອາທິດ + ບັນທຶກ ແລະ ວິເຄາະເປັນເວລາ 1 ອາທິດ + + "ຜູ້ພັດທະນາແອັບບໍ່ໄດ້ລະບຸວິທີທີ່ແອັບໃຊ້ຂໍ້ມູນຂອງທ່ານ." + - + + + + + + "ແອັບເລີ່ມຕົ້ນ" + "ບໍ່ມີແອັບເລີ່ມຕົ້ນ" + "ບໍ່ມີແອັບ" "ແອັບໂທລະສັບ" "ແອັບ SMS" "ແອັບໂປຣແກຣມທ່ອງເວັບ" "ແອັບຄັງ" "ແອັບເພງ" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml index 5662edd65..ac3333b69 100644 --- a/res/values-lt/strings.xml +++ b/res/values-lt/strings.xml @@ -97,7 +97,8 @@ "Pastarosios 15 minučių" "Leidimai nenaudoti" "Programos leidimų naudojimas" - "Prieš %1$s" + "Prieiga: Kartų: %1$s. Visa trukmė: %2$s. Paskutinį kartą naudota prieš %3$s." + "Prieiga: Kartų: %1$s. Paskutinį kartą naudota prieš %2$s." "Leisti" "Leisti visą laiką" "Leisti, tik kai programa naudojama" @@ -105,15 +106,11 @@ "Leidimas: %1$s" "Programos „%2$s“ prieiga prie %1$s" "Programa „%1$s“ prieš %3$s pasiekė: %2$s." - - + "Programa „%1$s“ neturėjo prieigos prie: %2$s." "Žiūrėti išsamią leidimų naudojimo informaciją" - - - - - - + "Paskutinį kartą pasiekta prieš %1$s" + "Leidžiama" + "Atmesta" %s diena %s dienos @@ -146,36 +143,37 @@ - + "Programos kūrėjas sako, kad duomenys gali būti:" + "Jei jums nepatinka, kaip programos kūrėjas naudoja jūsų duomenis, galite atmesti leidimą." + "Įkeliama į debesį" + "Įkeliama į debesį, kai aiškiai tai leidžiate" + "Bendrinama su reklamuotojais arba įmonėmis" + "Bendrinama su reklamuotojais arba įmonėmis, kai aiškiai tai leidžiate" + "Naudojama siekiant gauti pajamų" + "Naudojama siekiant gauti pajamų, kai aiškiai tai leidžiate" + "Visada išsaugoma ir analizuojama" + "Saugoma ir analizuojama nurodytą laikotarpį" + + Saugoma ir analizuojama %s savaitę + Saugoma ir analizuojama %s savaites + Saugoma ir analizuojama %s savaitės + Saugoma ir analizuojama %s savaičių + + "Programos kūrėjas nenurodė, kaip programa naudoja jūsų duomenis." + - + + + + + + "Numatytosios programos" + "Nėra jokių numatytųjų programų" + "Nėra jokių programų" "Telefono programa" "SMS programa" "Naršyklės programa" "Galerijos programa" "Muzikos programa" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml index 70e343b64..1c072dcea 100644 --- a/res/values-lv/strings.xml +++ b/res/values-lv/strings.xml @@ -96,7 +96,8 @@ "Pēdējās 15 minūtēs" "Nav lietota neviena atļauja" "Lietotņu atļauju lietojums" - "Pirms %1$s" + "Piekļuve: %1$s reizes. Kopējais ilgums: %2$s. Pēdējā lietošanas reize pirms šāda laika: %3$s." + "Piekļuve: %1$s reizes. Pēdējā lietošanas reize pirms šāda laika: %2$s." "Atļaut" "Vienmēr atļaut" "Atļaut tikai lietotnes izmantošanas laikā" @@ -104,15 +105,11 @@ "Atļauja: %1$s" "%1$s: lietotnes %2$s piekļuve" "%1$s piekļuva jūsu atļaujai %2$s pirms: %3$s." - - + "Lietotnei %1$s nav piekļuves %2$s." "Skatīt detalizētu informāciju par atļauju lietojumu" - - - - - - + "Pēdējā piekļuve pirms: %1$s" + "Atļauts" + "Noraidīts" %s dienu %s diena @@ -141,36 +138,36 @@ - + "Lietotnes izstrādātājs saka, ka jūsu dati, iespējams, ir:" + "Ja neesat apmierināts ar to, kā šis lietotnes izstrādātājs izmanto jūsu datus, varat noraidīt atļauju." + "Augšupielādēts mākonī" + "Augšupielādēts mākonī, ja jūs to skaidri atļaujat" + "Kopīgots ar reklāmdevējiem vai uzņēmumiem" + "Kopīgots ar reklāmdevējiem vai uzņēmumiem, ja jūs to skaidri atļaujat" + "Izmantots monetizācijai" + "Izmantots monetizācijai, ja jūs to skaidri atļaujat" + "Saglabāts un analizēts bezgalīgi" + "Saglabāts un analizēts tik ilgi, cik esat norādījis" + + Saglabāts un analizēts %s nedēļas + Saglabāts un analizēts %s nedēļu + Saglabāts un analizēts %s nedēļas + + "Lietotnes izstrādātājs nenorādīja, kā lietotne izmantos jūsu datus." + - + + + + + + "Noklusējuma lietotnes" + "Nav noklusējuma lietotņu" + "Nav lietotņu" "Lietotne Tālrunis" "Īsziņu lietotne" "Pārlūkprogrammas lietotne" "Galerijas lietotne" "Mūzikas lietotne" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml index 959feb1c2..0492805a2 100644 --- a/res/values-mk/strings.xml +++ b/res/values-mk/strings.xml @@ -95,7 +95,8 @@ "Последните 15 минути" "Не се користени дозволи" "Дозволи за апликација" - "Пред %1$s" + "Пристап: %1$s пати. Вкупно времетраење: %2$s. Последно користење пред %3$s." + "Пристап: %1$s пати. Последно користење пред %2$s." "Дозволи" "Дозволи цело време" "Дозволи само додека се користи апликацијата" @@ -103,15 +104,11 @@ "Пристап до %1$s" "Пристап до %1$s за %2$s" "%1$s пристапи до %2$s пред %3$s." - - + "%1$s не пристапила до вашата %2$s." "Прегледајте го деталното користење на дозволите" - - - - - - + "Последен пристап пред %1$s" + "Дозволени" + "Одбиени" %s ден %s дена @@ -136,36 +133,35 @@ - + "Програмерот на апликацијата вели дека вашите податоци може да:" + "Ако не ви се допаѓа како програмеров на аликацијата ги користи вашите податоци, може да ја одбиете дозволата." + "се прикачуваат во облак" + "се прикачуваат во облак кога експлицитно ќе го дозволите тоа" + "се споделуваат со огласувачи и бизниси" + "се споделуваат со огласувачи и бизниси кога експлицитно ќе го дозволите тоа" + "се користат за монетаризација" + "се користат за монетаризација кога експлицитно ќе го дозволите тоа" + "се зачувуваат и анализираат засекогаш" + "се зачувуваат и анализираат во времето што ќе го определите" + + се зачувуваат и анализираат %s седмица + се зачувуваат и анализираат %s седмици + + "Програмерот на апликацијата не назначил како апликацијата ги користи вашите податоци." + - + + + + + + "Стандардни апликации" + "Нема стандардни апликации" + "Нема апликации" "Апликација Телефон" "Апликација за SMS" "Прелистувач" "Апликација за галерија" "Апликација за музика" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml index ea4381a5d..202348c4a 100644 --- a/res/values-ml/strings.xml +++ b/res/values-ml/strings.xml @@ -95,7 +95,10 @@ "കഴിഞ്ഞ 15 മിനിറ്റ്" "അനുമതി ഉപയോഗങ്ങളൊന്നുമില്ല" "ആപ്പ് അനുമതികളുടെ ഉപയോഗം" - "%1$s മുമ്പ്" + + + + "അനുവദിക്കുക" "ഏതുസമയത്തും അനുവദിക്കുക" "ആപ്പ് ഉപയോഗത്തിലുള്ളപ്പോൾ മാത്രം അനുവദിക്കുക" @@ -103,15 +106,11 @@ "%1$s അനുമതി" "%2$s-നായുള്ള %1$s ആക്‌സസ്" "%1$s നിങ്ങളുടെ %2$s, %3$s മുമ്പ് ആക്‌സസ് ചെയ്‌തു." - - + "%1$s നിങ്ങളുടെ %2$sആക്‌‌സസ് ചെയ്‌തിട്ടില്ല." "അനുമതികളുടെ വിശദമായ ഉപയോഗം കാണുക" - - - - - - + "ഏറ്റവും അടുത്തിടെ ആക്‌സസ് ചെയ്‌തത് %1$s മുമ്പാണ്" + "അനുവദിച്ചവ" + "നിരസിച്ചവ" %s ദിവസം ഒരു ദിവസം @@ -136,36 +135,36 @@ - + "നിങ്ങളുടെ ഡാറ്റ ഇനിപ്പറയുന്ന രീതിയിൽ ഉപയോഗിച്ചേക്കാം എന്ന് ആപ്പ് ഡെവലപ്പർ പറയുന്നു:" + "ഈ ആപ്പ് ഡെവലപ്പർ നിങ്ങളുടെ ഡാറ്റ ഉപയോഗിക്കുന്ന രീതി ഇഷ്‌ടമല്ലെങ്കിൽ, അനുമതി നിരസിക്കാം." + "ക്ലൗഡിലേക്ക് അപ്‌ലോഡ് ചെയ്‌തേക്കാം" + "നിങ്ങൾ സ്‌പഷ്‌ടമായി അനുവദിക്കുമ്പോൾ ക്ലൗഡിലേക്ക് അപ്‌ലോഡ് ചെയ്‌തേക്കാം" + "പരസ്യദാതാക്കളുമായോ ബിസിനസുകളുമായോ പങ്കിട്ടേക്കാം" + "നിങ്ങൾ സ്‌പഷ്‌ടമായി അനുവദിക്കുമ്പോൾ പരസ്യദാതാക്കളുമായോ ബിസിനസുകളുമായോ പങ്കിട്ടേക്കാം" + "ധനം സമ്പാദിക്കാൻ ഉപയോഗിച്ചേക്കാം" + "നിങ്ങൾ സ്‌പഷ്‌ടമായി അനുവദിക്കുമ്പോൾ ധനം സമ്പാദിക്കാൻ ഉപയോഗിച്ചേക്കാം" + "ശാശ്വതമായി സംരക്ഷിച്ച് വിശകലനം ചെയ്‌തേക്കാം" + "നിങ്ങൾ വ്യക്തമാക്കുന്ന കാലയളവിൽ സംരക്ഷിച്ച് വിശകലനം ചെയ്‌തേക്കാം" + + %s ആഴ്‌ചത്തേയ്ക്ക് സംരക്ഷിച്ച് വിശകലനം ചെയ്‌തേക്കാം + ഒരാഴ്‌ചത്തേയ്ക്ക് സംരക്ഷിച്ച് വിശകലനം ചെയ്‌തേക്കാം + + "ആപ്പ് നിങ്ങളുടെ ഡാറ്റ ഉപയോഗിക്കുന്ന രീതി, ആപ്പ് ഡെവലപ്പർ വ്യക്തമാക്കിയിട്ടില്ല." + + + + + - + + + "ഡിഫോൾട്ട് ആപ്പുകൾ" + "ഡിഫോൾട്ട് ആപ്പുകൾ ഇല്ല" + "ഫോൺ ആപ്പ്" "SMS ആപ്പ്" "ബ്രൗസർ ആപ്പ്" "ഗാലറി ആപ്പ്" "സംഗീത ആപ്പ്" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml index 571c353c1..ec1fac1d2 100644 --- a/res/values-mn/strings.xml +++ b/res/values-mn/strings.xml @@ -95,7 +95,8 @@ "Сүүлийн 15 минут" "Зөвшөөрлийн хэрэглээ алга" "Аппын зөвшөөрлийн ашиглалт" - "%1$s-н өмнө" + "Хандалт: %1$s удаа. Нийт хугацаа: %2$s. Хамгийн сүүлд %3$s-н өмнө ашигласан." + "Хандалт: %1$s удаа. Хамгийн сүүлд %2$s-н өмнө ашигласан." "Зөвшөөрөх" "Ямар ч үед зөвшөөрөх" "Зөвхөн аппыг ашиглаж байх үед зөвшөөрөх" @@ -103,15 +104,11 @@ "%1$s-н зөвшөөрөл" "%2$s%1$s-н хандалт" "%1$s таны %2$s%3$s-н өмнө хандсан байна." - - + "%1$s таны %2$s-д хандаагүй байна." "Зөвшөөрлийн дэлгэрэнгүй ашиглалтыг харах" - - - - - - + "Хамгийн сүүлд %1$s-н өмнө хандсан" + "Зөвшөөрсөн" + "Татгалзсан" %s өдөр 1 өдөр @@ -136,36 +133,35 @@ - + "Апп хөгжүүлэгч таны өгөгдлийг дараах байдлаар ашиглаж болзошгүй:" + "Танд энэ апп хөгжүүлэгчийн таны өгөгдлийг хэрхэн ашиглаж байгаа нь таалагдахгүй байвал зөвшөөрлөөс татгалзаж болно." + "Үүлэнд байршуулна" + "Таныг тодорхой байдлааар зөвшөөрсөн тохиолдолд үүлэнд байршуулна" + "Сурталчлагчид эсвэл бизнесүүдтэй хуваалцана" + "Таныг тодорхой байдлаар зөвшөөрсөн тохиолдолд сурталчлагчид эсвэл бизнесүүдтэй хуваалцана" + "Мөнгө олох арга болгож ашиглана" + "Таныг тодорхой байдлаар зөвшөөрсөн тохиолдолд үүнийг мөнгө олох арга болгож ашиглана" + "Бүрмөсөн хадгалж, анализ хийнэ" + "Таны тогтоосон хугацааны турш хадгалж, анализ хийнэ" + + %s долоо хоногийн турш хадгалж, анализ хийнэ + 1 долоо хоногийн турш хадгалж, анализ хийнэ + + "Апп хөгжүүлэгч энэ апп таны өгөгдлийг хэрхэн ашиглах талаар тодорхойлоогүй байна." + - + + + + + + "Өгөгдмөл аппууд" + "Өгөгдмөл аппууд алга" + "Апп алга" "Гар утасны апп" "SMS апп" "Хөтөч апп" "Галерейны апп" "Хөгжмийн апп" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-mr-television/strings.xml b/res/values-mr-television/strings.xml index 4284becfc..381a00aa1 100644 --- a/res/values-mr-television/strings.xml +++ b/res/values-mr-television/strings.xml @@ -20,8 +20,8 @@ "तुम्ही हे नंतर सेटिंग्ज आणि अॅप्स मध्ये बदलू शकता" "%1$s / %2$s" "सिस्टम अॅप्स दाखवा" - "अॅप परवानग्या" - "अॅप परवानग्या" + "अ‍ॅप परवानग्या" + "अ‍ॅप परवानग्या" "%1$s परवानग्या" "अतिरिक्त परवानग्या" "%1$s परवानग्या" diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml index 946d3d42d..f7c0b29f2 100644 --- a/res/values-mr/strings.xml +++ b/res/values-mr/strings.xml @@ -20,14 +20,14 @@ "ओके" "परवानग्या" "रद्द करा" - "अॅप आढळले नाही" + "अ‍ॅप आढळले नाही" "नकार द्या" "अधिक माहिती" "तरीही नकार द्या" "%1$s पैकी %2$s" "<b>%1$s</b> ला %2$s ची परवानगी द्यायची का?" "<b>%1$s</b> ला नेहमी %2$s ची परवानगी द्यायची का?" - "फक्त अॅप वापरत असताना" + "फक्त अ‍ॅप वापरत असताना" "नेहमी" "नकार द्या आणि पुन्हा विचारू नका" "%1$d बंद केल्या" @@ -35,16 +35,16 @@ "कोणत्याही बंद केल्या नाहीत" "परवानगी द्या" "अॅप्स" - "अॅप परवानग्या" + "अ‍ॅप परवानग्या" "पुन्हा विचारू नका" "परवानग्या नाहीत" "अतिरिक्त परवानग्या" - "अॅप माहिती उघडा" + "अ‍ॅप माहिती उघडा" अधिक %1$d अधिक %1$d - "हे अॅप Android च्या जुन्या आवृत्तीसाठी डीझाइन करण्यात आले होते. परवानगी नाकारल्यामुळे ते यापुढे अपेक्षित असल्याप्रमाणे कार्य करणार नाही." + "हे अ‍ॅप Android च्या जुन्या आवृत्तीसाठी डीझाइन करण्यात आले होते. परवानगी नाकारल्यामुळे ते यापुढे अपेक्षित असल्याप्रमाणे कार्य करणार नाही." "अज्ञात क्रिया करा" "%1$d पैकी %2$d अ‍ॅप्सना परवानगी दिली" "सिस्टम दर्शवा" @@ -66,11 +66,11 @@ "नेहमी" - "फक्त अॅप वापरत असताना" + "फक्त अ‍ॅप वापरत असताना" "कधीही नाही" "लोड होत आहे…" "सर्व परवानग्या" - "अन्य अॅप क्षमता" + "अन्य अ‍ॅप क्षमता" "परवानगीची विनंती" "स्क्रीन ओव्हरले आढळले" "हे परवानगी सेटिंग बदलण्‍यासाठी, तुम्हाला सेटिंग्ज > अॅप्स मधून स्क्रीन ओव्हरले बंद करावे लागेल" @@ -83,7 +83,7 @@ "सुरू ठेवा" "नवीन परवानग्या" "वर्तमान परवानग्या" - "अॅप सुरुवातीच्या स्थितीत आहे…" + "अ‍ॅप सुरुवातीच्या स्थितीत आहे…" "अज्ञात" "परवानगी वापर" "%1$s - %2$s पूर्वी" @@ -94,24 +94,23 @@ "शेवटचा एक तास" "शेवटची १५ मिनिटे" "वापराची परवानगी नाही" - "अॅप परवानग्यांचा वापर" - "%1$s पूर्वी" + "अ‍ॅप परवानग्यांचा वापर" + + + + "अनुमती द्या" "सर्व वेळी अनुमती द्या" - "फक्त अॅप वापरत असताना अनुमती द्या" + "फक्त अ‍ॅप वापरत असताना अनुमती द्या" "नकार द्या" "%1$s परवानगी" "%1$s साठी %2$s अॅक्सेस केली" "%1$s ने तुमची %2$s %3$s पूर्वी अॅक्सेस केली." - - + "%1$s ला तुमच्या %2$sचा अॅक्सेस दिलेला नाही." "परवानग्यांचा वापर तपशीलवार पाहा" - - - - - - + "%1$s पूर्वीचा सर्वात अलीकडील अॅक्सेस" + "अनुमती असलेले" + "नाकारलेली" %s दिवस %s दिवस @@ -136,36 +135,36 @@ - - - - - "फोन अॅप" - "एसएमएस अॅप" - "ब्राउझर अॅप" - "गॅलरी अॅप" - "म्युझिक अॅप" - - - - - - - - - - - - - + "अॅप डेव्हलपरच्या म्हणण्यानुसार तुमचा डेटा कदाचित:" + "अॅप डेव्हलपर तुमचा डेटा ज्याप्रमाणे वापरतो ते जर तुम्हाला आवडत नसेल तर तुम्ही परवानगी नाकारू शकता." + "क्लाउडवर अपलोड केलेले" + "जेव्हा तुम्ही स्पष्टपणे परवानगी देता तेव्हा क्लाउडवर अपलोड केलेले" + "जाहिरातदार किंवा व्यवसायासोबत शेअर केलेले" + "तुम्ही स्पष्टपणे परवानगी देता तेव्हा जाहिरातदार किंवा व्यवसायासोबत शेअर केलेले" + "कमाईसाठी वापरलेला" + "तुम्ही स्पष्टपणे अनुमती देता तेव्हा कमाईसाठी वापरली जाते" + "सेव्ह आणि कायमस्वरूपी विश्लेषण केलेले" + "तुम्ही नमूद केलेल्या कालावधीसाठी सेव्ह आणि विश्लेषण केलेले" + + %sआठवड्यासाठी सेव्ह आणि विश्लेषण केलेले + %sआठवड्यांसाठी सेव्ह आणि विश्लेषण केलेले + + "अॅप किती डेटा वापरेल हे अॅप डेव्हलपरने नमूद केलेले नाही." + - + - + - + - - + "डीफॉल्ट अ‍ॅप्स" + "कोणतीही डीफॉल्‍ट अ‍ॅप्स नाहीत" + + "फोन अ‍ॅप" + "एसएमएस अ‍ॅप" + "ब्राउझर अ‍ॅप" + "गॅलरी अ‍ॅप" + "म्युझिक अ‍ॅप" diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml index 27cc5fefb..0487b18f9 100644 --- a/res/values-ms/strings.xml +++ b/res/values-ms/strings.xml @@ -95,7 +95,8 @@ "15 minit yang lalu" "Tiada penggunaan kebenaran" "Penggunaan kebenaran apl" - "%1$s yang lalu" + "Akses: %1$s kali. Jumlah tempoh: %2$s. Terakhir digunakan %3$s yang lalu." + "Akses: %1$s kali. Terakhir digunakan %2$s yang lalu." "Benarkan" "Benarkan sepanjang masa" "Benarkan hanya semasa apl sedang digunakan" @@ -103,15 +104,11 @@ "Kebenaran %1$s" "Akses %1$s untuk %2$s" "%1$s mengakses %2$s anda %3$s yang lalu." - - + "%1$s belum mengakses %2$s anda." "Lihat penggunaan kebenaran terperinci" - - - - - - + "Akses terbaharu %1$s yang lalu" + "Dibenarkan" + "Ditolak" %s hari 1 hari @@ -136,36 +133,35 @@ - + "Pembangun apl mengatakan bahawa data anda mungkin:" + "Jika anda tidak menyukai cara pembangun apl ini menggunakan data anda, anda boleh menolak kebenaran itu." + "Dimuat naik ke awan" + "Dimuat naik ke awan apabila anda membenarkannya secara jelas" + "Dikongsi dengan pengiklan atau perniagaan" + "Dikongsi dengan pengiklan atau perniagaan apabila anda membenarkannya secara jelas" + "Digunakan untuk pengewangan" + "Digunakan untuk pengewangan apabila anda membenarkannya secara jelas." + "Disimpan dan dianalisis selama-lamanya" + "Diimpan dan dianalisis untuk tempoh yang anda tetapkan" + + Disimpan dan dianalisis selama %s minggu + Disimpan dan dianalisis selama 1 minggu + + "Pembangun tidak menetapkan cara apl menggunakan data anda." + - + + + + + + "Apl lalai" + "Tiada apl lalai" + "Tiada apl" "Apl Telefon" "Apl SMS" "Apl penyemak imbas" "Apl Galeri" "Apl Muzik" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml index 269771461..b1fcab95a 100644 --- a/res/values-my/strings.xml +++ b/res/values-my/strings.xml @@ -95,7 +95,8 @@ "ပြီးခဲ့သော ၁၅ မိနစ်" "မည်သည့်ခွင့်ပြုချက်မှ မသုံးပါ" "အက်ပ်ခွင့်ပြုချက် အသုံးပြုမှု" - "ပြီးခဲ့သည့် %1$s က" + "အသုံးပြုမှု− %1$s ကြိမ်။ စုစုပေါင်း ကြာချိန်− %2$s။ ပြီးခဲ့သည့် %3$s က အသုံးပြုထားသည်။" + "အသုံးပြုမှု− %1$s ကြိမ်။ ပြီးခဲ့သည့် %2$s က အသုံးပြုခဲ့သည်။" "ခွင့်ပြုရန်" "အမြဲ ခွင့်ပြုရန်" "အက်ပ်အသုံးပြုချိန်တွင်သာ ခွင့်ပြုရန်" @@ -103,15 +104,11 @@ "%1$s ခွင့်ပြုချက်" "%2$s အတွက် %1$s ဝင်သုံးခွင့်" "%1$s က သင်၏ %2$s ကို ပြီးခဲ့သော %3$s က ဝင်သုံးထားသည်။" - - + "%1$s က သင်၏ %2$s ကို ဝင်သုံးမထားပါ။" "ခွင့်ပြုချက်များ အသုံးပြုမှု အသေးစိတ်ကို ကြည့်ရန်" - - - - - - + "လောလောလတ်လတ် %1$s အကြာက ဝင်သုံးထားသည်" + "ခွင့်ပြုထားသည်" + "ငြင်းပယ်ထားသည်" %s ရက် ၁ ရက် @@ -136,36 +133,35 @@ - + "အက်ပ်ဆော့ဖ်ဝဲအင်ဂျင်နီယာက သင့်ဒေတာများသည် အောက်ပါတို့ဖြစ်နိုင်သည်ဟု ဆိုပါသည်-" + "ဤအက်ပ်ဆော့ဖ်ဝဲအင်ဂျင်နီယာက သင့်ဒေတာများအား အသုံးပြုပုံကို မနှစ်သက်လျှင် ခွင့်ပြုချက်ကို သင်ငြင်းပယ်နိုင်သည်။" + "cloud သို့ အပ်လုဒ်လုပ်ထားသည်" + "သင်က ၎င်းကို တိကျပြတ်သားစွာ ခွင့်ပြုလျှင် cloud သို့ အပ်လုဒ်လုပ်ပါသည်" + "ကြော်ငြာရှင်များ သို့မဟုတ် လုပ်ငန်းများနှင့် မျှဝေထားသည်" + "သင်က ၎င်းကို တိကျပြတ်သားစွာ ခွင့်ပြုလျှင် ကြော်ငြာရှင်များ သို့မဟုတ် လုပ်ငန်းများနှင့် မျှဝေပါသည်" + "ဝင်ငွေရှာခြင်းအတွက် သုံးထားသည်" + "သင်က ၎င်းကို တိကျပြတ်သားစွာ ခွင့်ပြုလျှင် ဝင်ငွေရှာခြင်းအတွက် အသုံးပြုပါသည်" + "အမြဲတမ်းအတွက် သိမ်းပြီး ပိုင်းခြားစစ်ဆေးထားသည်" + "သင်သတ်မှတ်ထားသည့် ကာလအတွက် သိမ်းပြီး ပိုင်းခြားစစ်ဆေးထားသည်" + + %s ပတ်ကြာ သိမ်းပြီး ပိုင်းခြားစစ်ဆေးထားသည် + ၁ ပတ်ကြာ သိမ်းပြီး ပိုင်းခြားစစ်ဆေးထားသည် + + "အက်ပ်က သင့်ဒေတာကို မည်သို့အသုံးပြုမည်အား အက်ပ်ဆော့ဖ်ဝဲအင်ဂျင်နီယာက ဖော်ပြမထားပါ။" + - + + + + + + "မူရင်း အက်ပ်များ" + "မူရင်းအက်ပ်မရှိပါ" + "အက်ပ်တစ်ခုမျှ မရှိပါ" "ဖုန်းအက်ပ်" "SMS အက်ပ်" "ဘရောင်ဇာ အက်ပ်" "ပုံပြခန်းအက်ပ်" "တေးဂီတ အက်ပ်" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml index 69aff41d8..0d41de137 100644 --- a/res/values-nb/strings.xml +++ b/res/values-nb/strings.xml @@ -95,7 +95,8 @@ "De siste 15 minuttene" "Ingen bruk av tillatelsen" "Bruk av apptillatelser" - "for %1$s siden" + "Tilgang: %1$s ganger. Total varighet: %2$s. Sist brukt for %3$s siden." + "Tilgang: %1$s ganger. Sist brukt for %2$s siden." "Tillat" "Tillat hele tiden" "Bare tillat mens appen er i bruk" @@ -103,15 +104,11 @@ "%1$s-tillatelse" "%1$s-tilgang for %2$s" "%1$s har brukt %2$s for %3$s siden." - - + "%1$s har ikke brukt %2$s." "Vis detaljert bruk av tillatelser" - - - - - - + "Den nyeste tilgangen for %1$s siden" + "Tillatt" + "Avvist" %s dager 1 dag @@ -136,36 +133,35 @@ - + "Apputvikleren sier at dataene dine kan bli:" + "Hvis du ikke liker hvordan denne apputvikleren bruker dataene dine, kan du avvise tillatelsen." + "Lastet opp til nettskyen" + "Lastet opp til nettskyen når du uttrykkelig tillater det" + "Delt med annonsører eller bedrifter" + "Delt med annonsører eller bedrifter når du uttrykkelig tillater det" + "Brukt til inntektsgenerering" + "Brukt til inntektsgenerering når du uttrykkelig tillater det" + "Lagret og analysert for alltid" + "Lagret og analysert i varigheten du spesifiserer" + + Lagret og analysert i %s uker + Lagret og analysert i 1 uke + + "Apputvikleren spesifiserte ikke hvordan appen bruker dataene dine." + - + + + + + + "Standardapper" + "Ingen standardapper" + "Ingen apper" "Telefon-app" "SMS-app" "Nettleserapp" "Galleri-appen" "Musikk-appen" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml index 2b3bc6de5..e6ac5194c 100644 --- a/res/values-ne/strings.xml +++ b/res/values-ne/strings.xml @@ -95,7 +95,8 @@ "पछिल्लो १५ मिनेट" "उपयोगको अनुमति छैन" "अनुप्रयोगको अनुमतिको उपयोग" - "%1$s पहिले" + "पहुँच: %1$s पटक। कुल समय: %2$s। पछिल्लो पटक %3$s अघि प्रयोग गरिएको।" + "पहुँच: %1$s पटक। पछिल्लो पटक %2$s अघि प्रयोग गरिएको।" "अनुमति दिनुहोस्" "सधैँ अनुमति दिनुहोस्" "अनुप्रयोग प्रयोग भएको बेलामा मात्र अनुमति दिनुहोस्‌" @@ -103,15 +104,11 @@ "%1$s अनुमति" "%2$s का लागि %1$s को पहुँँच" "%1$s ले %3$s पहिले तपाईंको %2$s माथि पहुँच राख्यो।" - - + "%1$sतपाईंको %2$sमाथि पहुँच राखेको छैन।" "अनुमतिको विस्तृत उपयोग हेर्नुहोस्" - - - - - - + "सबैभन्दा पछिल्लो पटक %1$s अघि पहुँच राखिएको" + "अनुमति दिइएको" + "अस्वीकार गरिएको" %s दिन १ दिन @@ -136,36 +133,35 @@ - + "अनुप्रयोगको विकासकर्ताले भनेअनुसार तपाईंको डेटा निम्न प्रयोजनका लागि प्रयोग गर्न सकिन्छ:" + "तपाईंलार्इ यो अनुप्रयोगका विकासकर्ताले तपाईंको डेटा प्रयोग गर्ने तरिका मन पर्दैन भने तपाईं अनुमति नदिन सक्नुहुन्छ।" + "क्लाउडमा अपलोड गरिएको" + "तपाईंले स्पष्ट रूपमा अनुमति दिँदा क्लाउडमा अनलोड गरिन्छ" + "विज्ञापनदाता र व्यवसायसँग आदान प्रदान गरिन्छ" + "तपाईंले स्पष्ट रूपमा अनुमति दिँदा विज्ञापनदाता र व्यवसायसँग आदान प्रदान गरिन्छ" + "मुद्रीकरणका लागि प्रयोग गरिएको" + "तपाईंले स्पष्ट रूपमा अनुमति दिँदा मुद्रीकरणका लागि प्रयोग गरिन्छ।" + "सधैँका लागि सुरक्षित र विश्लेषण गरिन्छ" + "तपाईंले तोक्नुभएको अवधिका लागि सुरक्षित र विश्लेषण गरिएको" + + %s हप्ताका लागि सुरक्षित र विश्लेषण गरिएको + १ हप्ताका लागि सुरक्षित र विश्लेषण गरिएको + + "उक्त अनुप्रयोगको विकासकर्ताले अनुप्रयोगले तपाईंको डेटा प्रयोग गर्ने तरिका तोकेका थिएनन्।" + - + + + + + + "पूर्वनिर्धारित अनुप्रयोगहरू" + "कुनै पनि पूर्वनिर्धारित अनुप्रयोग छैन" + "कुनै पनि अनुप्रयोग छैन" "फोन अनुप्रयोग" "SMS अनुप्रयोग" "ब्राउजर अनुप्रयोग" "ग्यालरी अनुप्रयोग" "सङ्गीत अनुप्रयोग" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml index 1c22f2a14..44387dcbe 100644 --- a/res/values-nl/strings.xml +++ b/res/values-nl/strings.xml @@ -95,7 +95,8 @@ "Afgelopen 15 minuten" "Geen gebruik van machtigingen" "Gebruik van app-machtigingen" - "%1$s geleden" + "Toegang: %1$s keer. Totale duur: %2$s. Laatst gebruikt: %3$s geleden." + "Toegang: %1$s keer. Laatst gebruikt: %2$s geleden." "Toestaan" "Altijd toestaan" "Alleen toestaan terwijl de app wordt gebruikt" @@ -103,15 +104,11 @@ "%1$s-machtiging" "Toegang tot %1$s voor %2$s" "%1$s heeft %3$s geleden toegang tot je %2$s gehad." - - + "%1$s heeft geen toegang verkregen tot je %2$s." "Gedetailleerd machtigingsgebruik weergeven" - - - - - - + "Meest recente toegang: %1$s geleden" + "Toegestaan" + "Geweigerd" %s dagen 1 dag @@ -136,36 +133,35 @@ - + "Volgens de app-ontwikkelaar kan er het volgende gebeuren met je gegevens:" + "Als je het niet eens bent met de manier waarop deze app-ontwikkelaar je gegevens gebruikt, kun je de machtiging weigeren." + "Geüpload naar de cloud" + "Geüpload naar de cloud wanneer je dit expliciet toestaat" + "Gedeeld met adverteerders of bedrijven" + "Gedeeld met adverteerders of bedrijven wanneer je dit expliciet toestaat" + "Gebruikt voor inkomstenwerving" + "Gebruikt voor inkomstenwerving wanneer je dit expliciet toestaat" + "Zonder eindlimiet opgeslagen en geanalyseerd" + "Opgeslagen en geanalyseerd voor een duur die jij specificeert" + + %s weken opgeslagen en geanalyseerd + Eén week opgeslagen en geanalyseerd + + "De app-ontwikkelaar heeft niet gespecificeerd hoe de app je gegevens gebruikt." + - + + + + + + "Standaard-apps" + "Geen standaard-apps" + "Geen apps" "Telefoon-app" "Sms-app" "Browser-app" "Galerij-app" "Muziek-app" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml index 833bb4cbf..5a5a4ca1d 100644 --- a/res/values-or/strings.xml +++ b/res/values-or/strings.xml @@ -95,7 +95,8 @@ "ଶେଷ 15 ମିନିଟ୍" "ବ୍ୟବହାର ପାଇଁ କୌଣସି ଅନୁମତି ନାହିଁ" "ଆପ୍‍ ଅନୁମତି ବ୍ୟବହାର" - "%1$s ପୂର୍ବେ" + "ଆକ୍ସେସ୍‍: %1$sଥର। ସମୁଦାୟ ଅବଧି: %2$s। ଅନ୍ତିମ ଥର %3$s ପୂର୍ବେ ବ୍ୟବହୃତ ହୋଇଥିଲା।" + "ଆକ୍ସେସ୍‍: %1$sଥର। ଅନ୍ତିମ ଥର %2$s ପୂର୍ବେ ବ୍ୟବହୃତ ହୋଇଥିଲା।" "ଅନୁମତି ଦିଅନ୍ତୁ" "ସଦାବେଳେ ପାଇଁ ଅନୁମତି ଦିଅନ୍ତୁ" "ଆପ୍‍ ବ୍ୟବହାରରେ ରହିଥିବା ବେଳେ କେବଳ ଅନୁମତି କରନ୍ତୁ" @@ -103,15 +104,11 @@ "%1$s ଅନୁମତି" "%1$s %2$s ପାଇଁ ଆକ୍ସେସ୍‍ କରନ୍ତୁ" "%1$s %3$s ପୂର୍ବେ ଆପଣଙ୍କ %2$s ଆକ୍ସେସ୍‍ କରିିିିଥିଲେ।" - - + "%1$s ଆପଣଙ୍କ %2$s ଆକ୍ସେସ୍‍ ନାହିଁ।" "ବିସ୍ତୃତ ଅନୁମତି ବ୍ୟବହାର ଦେଖନ୍ତୁ" - - - - - - + "%1$s ପୂର୍ବେ ହୋଇଥିବା ଆକ୍ସେସ୍‍" + "ଅନୁମୋଦିତ" + "ପ୍ରତ୍ୟାଖ୍ୟାନ କରାଗଲା" %s ଦିନ 1 ଦିନ @@ -136,36 +133,35 @@ - + "ଆପ୍‍ ଡେଭେଲପର୍‍ କୁହେ ଆପଣଙ୍କ ଡାଟା ହୁଏତ:" + "ଯଦି ଆପଣ ଏହି ଆପ୍‍ ଡେଭେଲପର୍‍ ଆପଣଙ୍କ ଡାଟା କିପରି ବ୍ୟବହାର କରୁଛନ୍ତି ତାହା ପସନ୍ଦ କରୁ ନାହାଁନ୍ତି ତେବେ ଆପଣ ଅନୁମତି ଅଗ୍ରାହ୍ୟ କରିପାରିବେ।" + "କ୍ଲାଉଡ୍‍କୁ‍ ଅପ୍‍‍‍‍‍ଲୋଡ୍‍ ହୋଇଛି" + "ଯେତେବେଳେ ଆପଣ ଏହାକୁ ସ୍ପଷ୍ଟଭାବରେ ଅନୁମତି କରିବେ ସେତେବେଳେ ଆପଣ କ୍ଲାଉଡ୍‍କୁ ଅପ୍‍‍‍‍‍‍‍ଲୋଡ୍‍‍‍ ହେବ" + "ବିଜ୍ଞାପନଦାତା କିମ୍ବା ବ୍ୟବସାୟ ସହ ସେୟାର୍‍ ହୋଇଛି" + "ଯେତେବେଳେ ଆପଣ ଏହାକୁ ସ୍ପଷ୍ଟଭାବରେ ଅନୁମତି କରିବେ ସେତେବେଳେ ବିଜ୍ଞାପନଦାତା ବା ବ୍ୟବସାୟଗୁଡିକ ସହ ସେୟାର୍‍ କରାଯିବ" + "ମୋନେଟାଇଜେସନ୍‍ ପାଇଁ ବ୍ୟବହୃତ ହୋଇଛି" + "ଯେତେବେଳେ ଆପଣ ସ୍ପଷ୍ଟଭାବରେ ଏହାକୁ ଅନୁମତି ଲରିଏବ ମୋନେଟାଇଜେସନ୍‍ ପାଇଁ ବ୍ୟବହୃତ ହେବ" + "ସେଭ୍‍ ହୋଇଛି ଏବଂ ସର୍ବଦା ପାଇଁ ବ୍ୟାଖ୍ୟା କରାଯାଇଛି" + "ଆପଣ ନିର୍ଦ୍ଧିଷ୍ଟ କରିଥିବା ଏକ ଅବଧି ପାଇଁ ସେଭ୍‍ ହେବା ସହ ବ୍ୟାଖ୍ୟା କରାଯାଇଛି" + + %s ସପ୍ତାହ ପାଇଁ ସେଭ୍‍ ହେବା ସହ ବ୍ୟାଖ୍ୟା କରାଯାଇଛି + 1 ସପ୍ତାହ ପାଇଁ ସେଭ୍‍ ହେବା ସହ ବ୍ୟାଖ୍ୟା କରାଯାଇଛି + + "ଆପ୍‍ ଆପଣଙ୍କ ଡାଟା କିପରି ବ୍ୟବହାର କରେ ଏହି ଆପ୍‍ ଡେଭେଲପର୍‍ ନିର୍ଦ୍ଧିଷ୍ଟ କରି ନାହାଁନ୍ତି।" + - + + + + + + "ଡିଫଲ୍ଟ ଆପ୍ସ" + "କୌଣସି ଡିଫଲ୍ଟ ଆପ୍ସ ନାହିଁ" + "କୌଣସି ଆପ୍‌ ନାହିଁ" "ଫୋନ୍‌ ଆପ୍‌" "SMS ଆପ୍‌" "ବ୍ରାଉଜର୍‌ ଆପ୍‌" "Gallery ଆପ୍‍" "Music ଆପ୍‍" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml index e0d563d99..59fa690c3 100644 --- a/res/values-pa/strings.xml +++ b/res/values-pa/strings.xml @@ -95,7 +95,10 @@ "ਪਿਛਲੇ 15 ਮਿੰਟ" "ਕੋਈ ਇਜਾਜ਼ਤ ਨਹੀਂ ਵਰਤੀ ਗਈ" "ਐਪ ਇਜਾਜ਼ਤਾਂ ਵਰਤੋ" - "%1$s ਪਹਿਲਾਂ" + + + + "ਕਰਨ ਦਿਓ" "ਹਰ ਵੇਲੇ ਕਰਨ ਦਿਓ" "ਸਿਰਫ਼ ਐਪ ਵਰਤੇ ਜਾਣ ਵੇਲੇ ਕਰਨ ਦਿਓ" @@ -103,15 +106,11 @@ "%1$s ਇਜਾਜ਼ਤ" "%2$s ਲਈ %1$s ਪਹੁੰਚ" "%1$s ਨੇ %3$s ਪਹਿਲਾਂ ਤੁਹਾਡੇ %2$s ਤੱਕ ਪਹੁੰਚ ਕੀਤੀ।" - - + "%1$s ਨੇ ਤੁਹਾਡੇ %2$s ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ।" "ਇਜਾਜ਼ਤਾਂ ਦੀ ਵਰਤੋਂ ਵੇਰਵੇ-ਸਹਿਤ ਦੇਖੋ" - - - - - - + "ਸਭ ਤੋਂ ਹਾਲੀਆ ਪਹੁੰਚ %1$s ਪਹਿਲਾਂ" + "ਮਨਜ਼ੂਰਸ਼ੁਦਾ" + "ਗੈਰ-ਮਨਜ਼ੂਰਸ਼ੁਦਾ" %s ਦਿਨ %s ਦਿਨ @@ -136,36 +135,36 @@ - + "ਐਪ ਵਿਕਾਸਕਾਰ ਦਾ ਕਹਿਣਾ ਹੈ ਕਿ ਸ਼ਾਇਦ ਤੁਹਾਡੇ ਡਾਟੇ ਨੂੰ:" + "ਜੇ ਤੁਹਾਨੂੰ ਐਪ ਵਿਕਾਸਕਾਰ ਵੱਲੋਂ ਤੁਹਾਡਾ ਡਾਟਾ ਵਰਤੇ ਜਾਣਾ ਪਸੰਦ ਨਹੀਂ ਹੈ, ਤਾਂ ਤੁਸੀਂ ਇਜਾਜ਼ਤ ਨੂੰ ਅਸਵੀਕਾਰ ਕਰ ਸਕਦੇ ਹੋ।" + "ਕਲਾਊਡ \'ਤੇ ਅੱਪਲੋਡ ਕੀਤਾ ਜਾਂਦਾ ਹੈ" + "ਤੁਹਾਡੇ ਵੱਲੋਂ ਸਾਫ਼ ਤੌਰ \'ਤੇ ਇੰਝ ਕਰਨ ਦੇਣ ਕਰਕੇ ਡਾਟਾ ਕਲਾਊਡ \'ਤੇ ਅੱਪਲੋਡ ਕੀਤਾ ਜਾਂਦਾ ਹੈ" + "ਵਿਗਿਆਪਨਦਾਤਾਵਾਂ ਜਾਂ ਕਾਰੋਬਾਰਾਂ ਨਾਲ ਸਾਂਝਾ ਕੀਤਾ ਜਾਂਦਾ ਹੈ" + "ਤੁਹਾਡੇ ਵੱਲੋਂ ਸਾਫ਼ ਤੌਰ \'ਤੇ ਇੰਝ ਕਰਨ ਦੇਣ ਕਰਕੇ ਵਿਗਿਆਪਨਦਾਤਾਵਾਂ ਜਾਂ ਕਾਰੋਬਾਰਾਂ ਨਾਲ ਸਾਂਝਾ ਕੀਤਾ ਜਾਂਦਾ ਹੈ" + "ਮੁਦਰੀਕਰਨ ਲਈ ਵਰਤਿਆ ਜਾਂਦਾ ਹੈ" + "ਤੁਹਾਡੇ ਵੱਲੋਂ ਸਾਫ਼ ਤੌਰ \'ਤੇ ਇੰਝ ਕਰਨ ਦੇਣ ਕਰਕੇ ਇਹ ਮੁਦਰੀਕਰਨ ਲਈ ਵਰਤਿਆ ਜਾਂਦਾ ਹੈ" + "ਹਮੇਸ਼ਾਂ ਰੱਖਿਅਤ ਕੀਤਾ ਅਤੇ ਵਿਸ਼ਲੇਸ਼ਣ ਕੀਤਾ ਜਾਂਦਾ ਹੈ" + "ਤੁਹਾਡੇ ਵੱਲੋਂ ਦੱਸੀ ਇੱਕ ਮਿਆਦ ਲਈ ਰੱਖਿਅਤ ਕੀਤਾ ਅਤੇ ਵਿਸ਼ਲੇਸ਼ਣ ਕੀਤਾ ਜਾਂਦਾ ਹੈ" + + %s ਹਫ਼ਤੇ ਲਈ ਰੱਖਿਅਤ ਕੀਤਾ ਅਤੇ ਵਿਸ਼ਲੇਸ਼ਣ ਕੀਤਾ ਜਾਂਦਾ ਹੈ + %s ਹਫ਼ਤਿਆਂ ਲਈ ਰੱਖਿਅਤ ਕੀਤਾ ਅਤੇ ਵਿਸ਼ਲੇਸ਼ਣ ਕੀਤਾ ਜਾਂਦਾ ਹੈ + + "ਐਪ ਵਿਕਾਸਕਾਰ ਨੇ ਐਪ ਵੱਲੋਂ ਤੁਹਾਡਾ ਡਾਟਾ ਵਰਤੇ ਜਾਣ ਬਾਰੇ ਕੁਝ ਨਹੀਂ ਦੱਸਿਆ ਹੈ।" + + + + + - + + + "ਪੂਰਵ-ਨਿਰਧਾਰਤ ਐਪਾਂ" + "ਕੋਈ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਐਪਾਂ ਨਹੀਂ" + "ਫ਼ੋਨ ਐਪ" "SMS ਐਪ" "ਬ੍ਰਾਊਜ਼ਰ ਐਪ" "ਗੈਲਰੀ ਐਪ" "ਸੰਗੀਤ ਐਪ" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml index 52f187355..2e504d295 100644 --- a/res/values-pl/strings.xml +++ b/res/values-pl/strings.xml @@ -97,7 +97,8 @@ "Ostatnie 15 minut" "Brak użycia uprawnień" "Użycie uprawnień aplikacji" - "%1$s temu" + "Dostęp: %1$s razy. Całkowity czas trwania: %2$s. Ostatnio użyto %3$s temu." + "Dostęp: %1$s razy. Ostatnio użyto %2$s temu." "Zezwól" "Zawsze zezwalaj" "Zezwalaj tylko podczas używania aplikacji" @@ -105,15 +106,11 @@ "Uprawnienie dostępu do: %1$s" "Dostęp do: %1$s dla aplikacji %2$s" "Aplikacja %1$s użyła dostępu do: %2$s %3$s temu." - - + "Aplikacja %1$s nie korzysta z: %2$s." "Wyświetl szczegółowe użycie uprawnień" - - - - - - + "Ostatnie użycie %1$s temu" + "Dozwolone" + "Niedozwolone" %s dni %s dni @@ -146,36 +143,37 @@ - + "Zgodnie z informacjami od dewelopera aplikacji Twoje dane mogą być:" + "Jesli nie podoba Ci się sposób, w jaki deweloper tej aplikacji używa Twoich danych, możesz nie przyznawać uprawnień." + "Przesyłane do chmury." + "Przesyłane do chmury, gdy na to wyraźnie zezwolisz." + "Udostępniane reklamodawcom lub firmom." + "Udostępniane reklamodawcom lub firmom, gdy na to wyraźnie zezwolisz." + "Używane do generowania przychodu." + "Używane do generowania przychodu, gdy wyraźnie na to zezwolisz." + "Zapisane trwale i zawsze analizowane." + "Zapisywane i analizowane przez określony przez Ciebie czas." + + Zapisywane i analizowane przez %s tygodnie + Zapisywane i analizowane przez %s tygodni + Zapisywane i analizowane przez %s tygodnia + Zapisywane i analizowane przez tydzień. + + "Deweloper aplikacji nie określił, jak aplikacja używa Twoich danych." + - + + + + + + "Aplikacje domyślne" + "Brak domyślnych aplikacji" + "Brak aplikacji" "Telefon" "Aplikacja do SMS-ów" "Przeglądarka" "Aplikacja Galeria" "Aplikacja Muzyka" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-pt-rBR/strings.xml b/res/values-pt-rBR/strings.xml index 324157c40..009d1d7e0 100644 --- a/res/values-pt-rBR/strings.xml +++ b/res/values-pt-rBR/strings.xml @@ -95,7 +95,8 @@ "Últimos 15 minutos" "Nenhum uso de permissões" "Uso de permissões do app" - "Há %1$s" + "Acesso: %1$s vezes. Duração total: %2$s. Última utilização: %3$s atrás." + "Acesso: %1$s vezes. Última utilização: %2$s atrás." "Permitir" "Permitir o tempo todo" "Permitir apenas enquanto o app estiver em uso" @@ -103,15 +104,11 @@ "Permissão de %1$s" "Acesso à permissão de %1$s para o app %2$s" "O app %1$s acessou sua permissão de %2$s %3$s atrás." - - + "O app %1$s não acessou seu %2$s." "Ver uso detalhado das permissões" - - - - - - + "Acesso mais recente há %1$s" + "Permitida" + "Negada" %s dia %s dias @@ -136,36 +133,35 @@ - + "O desenvolvedor do app avisa que seus dados podem ser:" + "Se não estiver satisfeito com o uso que o desenvolvedor faz dos seus dados, negue a permissão." + "enviados para a nuvem;" + "enviados para a nuvem quando há sua permissão explícita;" + "compartilhados com anunciantes ou empresas;" + "compartilhados com anunciantes ou empresas quando há sua permissão explícita;" + "usados para monetização;" + "usados para monetização quando há sua permissão explícita;" + "salvos e analisados permanentemente;" + "salvos e analisados pela duração especificada por você;" + + salvos e analisados por %s semana; + salvos e analisados por %s semanas;​ + + "O desenvolvedor do app não especificou como seus dados são usados." + - + + + + + + "Apps padrão" + "Nenhum app padrão" + "Nenhum app" "App Telefone" "App de SMS" "App de navegação" "App de galeria" "App de música" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml index 511de8c5c..d19126727 100644 --- a/res/values-pt-rPT/strings.xml +++ b/res/values-pt-rPT/strings.xml @@ -95,7 +95,8 @@ "Últimos 15 minutos" "Autorizações não utilizadas" "Utiliz. de autoriz. da app" - "Há %1$s" + "Acesso: %1$s vezes. Duração total: %2$s. Última utilização há %3$s." + "Acesso: %1$s vezes. Última utilização há %2$s." "Permitir" "Permitir sempre" "Permitir apenas enquanto a aplicação está a ser utilizada" @@ -132,13 +133,6 @@ - "Aplicações predefinidas" - "Sem aplicações predefinidas" - "Aplicação Telefone" - "Aplicação de SMS" - "Aplicação de navegador" - "Aplicação de galeria" - "Aplicação de música" "O programador da aplicação afirma que os seus dados podem ser:" "Se não gostar da forma como o programador desta aplicação está a utilizar os seus dados, pode recusar a autorização." "Carregados para a nuvem." @@ -154,4 +148,20 @@ Guardados e analisados durante 1 semana. "O programador da aplicação não especificou de que forma a aplicação utiliza os seus dados." + + + + + + + + + "Aplicações predefinidas" + "Sem aplicações predefinidas" + "Sem aplicações" + "Aplicação Telefone" + "Aplicação de SMS" + "Aplicação de navegador" + "Aplicação de galeria" + "Aplicação de música" diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml index 324157c40..009d1d7e0 100644 --- a/res/values-pt/strings.xml +++ b/res/values-pt/strings.xml @@ -95,7 +95,8 @@ "Últimos 15 minutos" "Nenhum uso de permissões" "Uso de permissões do app" - "Há %1$s" + "Acesso: %1$s vezes. Duração total: %2$s. Última utilização: %3$s atrás." + "Acesso: %1$s vezes. Última utilização: %2$s atrás." "Permitir" "Permitir o tempo todo" "Permitir apenas enquanto o app estiver em uso" @@ -103,15 +104,11 @@ "Permissão de %1$s" "Acesso à permissão de %1$s para o app %2$s" "O app %1$s acessou sua permissão de %2$s %3$s atrás." - - + "O app %1$s não acessou seu %2$s." "Ver uso detalhado das permissões" - - - - - - + "Acesso mais recente há %1$s" + "Permitida" + "Negada" %s dia %s dias @@ -136,36 +133,35 @@ - + "O desenvolvedor do app avisa que seus dados podem ser:" + "Se não estiver satisfeito com o uso que o desenvolvedor faz dos seus dados, negue a permissão." + "enviados para a nuvem;" + "enviados para a nuvem quando há sua permissão explícita;" + "compartilhados com anunciantes ou empresas;" + "compartilhados com anunciantes ou empresas quando há sua permissão explícita;" + "usados para monetização;" + "usados para monetização quando há sua permissão explícita;" + "salvos e analisados permanentemente;" + "salvos e analisados pela duração especificada por você;" + + salvos e analisados por %s semana; + salvos e analisados por %s semanas;​ + + "O desenvolvedor do app não especificou como seus dados são usados." + - + + + + + + "Apps padrão" + "Nenhum app padrão" + "Nenhum app" "App Telefone" "App de SMS" "App de navegação" "App de galeria" "App de música" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml index 372f0e591..2184f6ea0 100644 --- a/res/values-ro/strings.xml +++ b/res/values-ro/strings.xml @@ -96,7 +96,8 @@ "Ultimele 15 minute" "Nicio permisiune folosită" "Utilizare permisiuni pentru aplicație" - "Acum %1$s" + "Acces: %1$s ori. Durată totală: %2$s. Ultima utilizare: acum %3$s." + "Acces: %1$s ori. Ultima utilizare: acum %2$s." "Permiteți" "Permiteți întotdeauna" "Permiteți numai când aplicația este folosită" @@ -104,15 +105,11 @@ "Permisiune %1$s" "Acces la %1$s pentru aplicația %2$s" "Aplicația %1$s a accesat %2$s acum %3$s." - - + "%1$s nu a accesat %2$s." "Afișați utilizarea detaliată a permisiunilor" - - - - - - + "Accesul cel mai recent acum %1$s" + "Permise" + "Respinse" %s zile %s de zile @@ -141,36 +138,36 @@ - + "Dezvoltatorul aplicației afirmă că datele pot fi:" + "Dacă nu vă place cum folosește dezvoltatorul aplicației datele dvs., îi puteți refuza permisiunea." + "Încărcate în cloud" + "Încărcate în cloud când permiteți în mod explicit" + "Distribuite advertiserilor sau companiilor" + "Distribuite advertiserilor sau companiilor când permiteți explicit" + "Folosite pentru generare de bani" + "Folosite pentru generare de bani când permiteți explicit" + "Salvate și analizate permanent" + "Salvate și analizate pe durata specificată de dvs." + + Salvate și analizate timp de %s săptămâni + Salvate și analizate timp de %s de săptămâni + Salvate și analizate timp de 1 săptămână + + "Dezvoltatorul aplicației nu a specificat cum folosește aplicația datele dvs." + - + + + + + + "Aplicații prestabilite" + "Nicio aplicație prestabilită." + "Nicio aplicație" "Aplicația Telefon" "Aplicația SMS" "Aplicația Browser" "Aplicația Galerie" "Aplicația Muzică" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index c6a52989c..647b742c8 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -97,7 +97,8 @@ "Последние 15 минут" "Разрешения не использовались" "Использование разрешений" - "%1$s назад" + "Количество запросов на доступ: %1$s. Общее время использования: %2$s. Последний раз: %3$s назад." + "Количество запросов на доступ: %1$s. Последний раз: %2$s назад." "Разрешить" "Разрешить в любом режиме" "Разрешить только в активном режиме" @@ -105,15 +106,11 @@ "Разрешение \"%1$s\"" "Доступ к разрешению \"%1$s\" для приложения \"%2$s\"." "Приложение \"%1$s\" получило доступ к разрешению \"%2$s\" %3$s назад." - - + "Приложение \"%1$s\" не обратилось к следующему разрешению: %2$s." "Показать подробную информацию об использовании разрешений" - - - - - - + "Последнее обращение: %1$s назад" + "Предоставленные разрешения" + "Отсутствующие разрешения" %s день %s дня @@ -146,36 +143,37 @@ - + "Разработчик приложения заявляет, что ваши данные могут:" + "Не предоставляйте разрешения, если вы не согласны с тем, как разработчик приложения собирается использовать ваши данные." + "Загружаться в облачное хранилище." + "Загружаться в облачное хранилище с вашего явного согласия." + "Предоставляться рекламодателям и коммерческим компаниям." + "Предоставляться рекламодателям и коммерческим компаниям с вашего явного согласия." + "Использоваться в коммерческих целях." + "Использоваться в коммерческих целях с вашего явного согласия." + "Храниться и использоваться для анализа в течение неограниченного времени." + "Храниться и использоваться для анализа на протяжении указанного вами времени." + + Храниться и использоваться для анализа в течение %s недели. + Храниться и использоваться для анализа в течение %s недель. + Храниться и использоваться для анализа в течение %s недель. + Храниться и использоваться для анализа в течение %s недели. + + "Разработчик приложения не указал, как приложение будет использовать ваши данные." + - + + + + + + "Приложения по умолчанию" + "Нет приложений по умолчанию" + "Приложений нет" "Приложение для звонков" "Приложение для SMS" "Браузер" "Галерея" "Музыка" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml index 4ffc78542..19f1e0551 100644 --- a/res/values-si/strings.xml +++ b/res/values-si/strings.xml @@ -95,7 +95,8 @@ "පසුගිය මිනිත්තු 15" "අවසර භාවිත නැත" "යෙදුම් අවසර භාවිතය" - "%1$sකට පෙර" + "ප්‍රවේශය: වාර %1$s. මුළු කාලය: %2$s. අවසන් වරට භාවිත කළේ %3$s ඉහතය." + "ප්‍රවේශය: වාර %1$s. අවසන් වරට භාවිත කළේ %2$s කට ඉහතය." "ඉඩ දෙන්න" "සැම විටම ඉඩ දෙන්න" "යෙදුම භාවිතයේදී පමණක් ඉඩ දෙන්න" @@ -103,15 +104,11 @@ "%1$s අවසරය" "%2$s සඳහා %1$s ප්‍රවේශය" "%1$s ඔබේ %2$s %3$sකට පෙර පිවිසියා." - - + "%1$s ඔබේ %2$s වෙත පිවිස නැත." "විස්තරාත්මක අවසර භාවිතය බලන්න" - - - - - - + "%1$sකට පෙර වඩාත්ම මෑත පිවිසීම" + "ඉඩ දුන්" + "ප්‍රතික්ෂේපයි" දින %s දින %s @@ -136,36 +133,35 @@ - + "යෙදුම් සංවර්ධක පවසන්නේ ඔබේ දත්ත:" + "ඔබ මෙම යෙදුම් සංවර්ධක ඔබේ දත්ත භාවිත කරන ආකාරයට අකමැති නම් ඔබට අවසරය ප්‍රතික්ෂේප කළ හැකිය." + "වලාකුළට උඩුගත කෙරේ" + "ඔබ එයට ප්‍රකාශිතව ඉඩ දුන් විට වලාකුළට උඩුගත කෙරේ" + "වෙළඳ ප්‍රචාරකයන් හෝ ව්‍යාපාර සමග බෙදා ගැනේ" + "ඔබ එයට ප්‍රකාශිතව ඉඩ දුන් විට වෙළඳ ප්‍රචාරකයන් හෝ ව්‍යාපාර සමග බෙදා ගැනේ" + "මුදල් රැස් කිරීම සඳහා භාවිතා වේ" + "ඔබ එයට ප්‍රකාශිතව ඉඩ දුන් විට මුදල් රැස් කිරීමට භාවිත කෙරේ" + "සදහටම සුරැක විශ්ලේෂණය කෙරේ" + "ඔබ සඳහන් කරන කාල සීමාවක් සඳහා සුරැකීම සහ විශ්ලේෂණය කිරීම සිදු කෙරේ" + + සති %sක් සුරැකීම සහ විශ්ලේෂණය කිරීම සිදු කෙරේ + සති %sක් සුරැකීම සහ විශ්ලේෂණය කිරීම සිදු කෙරේ + + "යෙදුම් සංවර්ධක යෙදුම ඔබේ දත්ත භාවිත කරන ආකාරය සඳහන් කර නැත." + - + + + + + + "පෙරනිමි යෙදුම්" + "පෙරනිමි යෙදුම් නැත" + "යෙදුම් නොමැත" "දුරකථන යෙදුම" "කෙටි පණිවුඩ යෙදුම" "බ්‍රවුසර යෙදුම" "Gallery යෙදුම" "සංගීත යෙදුම" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml index de4b445d3..022a68858 100644 --- a/res/values-sk/strings.xml +++ b/res/values-sk/strings.xml @@ -97,7 +97,8 @@ "Posledných 15 minút" "Žiadne využitie povolení" "Využitie povolení aplikácie" - "pred %1$s" + "Prístup: %1$s‑krát. Celkové trvanie: %2$s. Naposledy použité pred %3$s." + "Prístup: %1$s‑krát. Naposledy použité pred %2$s." "Povoliť" "Povoliť po celý čas" "Povoliť iba počas používania aplikácie" @@ -105,15 +106,11 @@ "Povolenie %1$s" "Prístup k %1$s pre %2$s" "Aplikácia %1$s použila %2$s pred %3$s." - - + "%1$s nemôže používať povolenie %2$s." "Zobraziť podrobné údaje o využití povolení" - - - - - - + "Naposledy použité pred %1$s" + "Povolené" + "Zamietnuté" %s dni %s dňa @@ -146,36 +143,37 @@ - + "Vývojár aplikácie tvrdí, že vaše údaje môžu byť:" + "Ak sa vám nepáči, ako tento vývojár aplikácie používa vaše údaje, môžete toto povolenie zamietnuť." + "Nahrané do cloudu" + "Nahrané do cloudu, keď to výslovne povolíte" + "Zdieľané s inzerentmi alebo firmami" + "Zdieľané s inzerentmi alebo firmami, keď to výslovne povolíte" + "Používané na speňaženie" + "Použijú sa na speňaženie, keď to výslovne povolíte" + "Uložené a analyzované navždy" + "Uložené a analyzované na obdobie, ktoré špecifikujete" + + Uložené a analyzované na %s týždne + Uložené a analyzované na %s týždňa + Uložené a analyzované na %s týždňov + Uložené a analyzované na 1 týždeň + + "Vývojár nešpecifikoval, ako jeho aplikácia používa údaje." + - + + + + + + "Predvolené aplikácie" + "Žiadne predvolené aplikácie" + "Žiadne aplikácie" "Aplikácia Telefón" "Aplikácia pre SMS a MMS" "Prehliadač" "Aplikácia Galéria" "Aplikácia Hudba" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml index 72f085888..2489c5935 100644 --- a/res/values-sl/strings.xml +++ b/res/values-sl/strings.xml @@ -97,7 +97,8 @@ "Zadnjih 15 minut" "Ni uporabe dovoljenj" "Uporaba dovoljenj aplikacije" - "pred %1$s" + "Dostop: %1$s-krat. Skupno trajanje: %2$s. Nazadnje uporabljeno pred %3$s." + "Dostop: %1$s-krat. Nazadnje uporabljeno pred %2$s." "Dovoli" "Vedno dovoli" "Dovoli samo, ko je aplikacija v uporabi" @@ -105,15 +106,11 @@ "Dovoljenje %1$s" "Dostop do dovoljenja %1$s za aplikacijo %2$s" "Aplikacija %1$s je do dovoljenja %2$s dostopala pred %3$s." - - + "Aplikacija %1$s ni dostopila do: %2$s." "Podroben prikaz uporabe dovoljenj" - - - - - - + "Zadnji dostop pred %1$s" + "Dovoljeno" + "Zavrnjeno" %s dnevom %s dnevoma @@ -146,36 +143,37 @@ - + "Razvijalec aplikacije navaja, da so vaši podatki lahko:" + "Če vam ni všeč, kako razvijalec te aplikacije uporablja vaše podatke, lahko dovoljenje zavrnete." + "Naloženi v oblak" + "Naloženi v oblak, ko to izrecno dovolite" + "Posredovani oglaševalcem ali podjetjem" + "Posredovani oglaševalcem ali podjetjem, ko to izrecno dovolite" + "Uporabljeni za ovrednotenje" + "Uporabljeni za ovrednotenje, ko to izrecno dovolite" + "Shranjeni in analizirani za vedno" + "Shranjeni in analizirani za obdobje, ki ga določite" + + Shranjeni in analizirani %s teden + Shranjeni in analizirani %s tedna + Shranjeni in analizirani %s tedne + Shranjeni in analizirani %s tednov + + "Razvijalec aplikacije ni določil, kako aplikacija uporablja vaše podatke." + - + + + + + + "Privzete aplikacije" + "Ni privzetih aplikacij" + "Ni aplikacij" "Aplikacija Telefon" "Aplikacija za SMS-je" "Brskalnik" "Aplikacija Galerija" "Aplikacija Glasba" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml index 99a8a0013..67ed55b41 100644 --- a/res/values-sq/strings.xml +++ b/res/values-sq/strings.xml @@ -95,7 +95,8 @@ "15 minutat e fundit" "Nuk ka përdorime të lejeve" "Përdorimi i lejeve të apl." - "%1$s më parë" + "Qasja: %1$s herë. Kohëzgjatja gjithsej: %2$s. Përdorur së fundi %3$s më parë." + "Qasja: %1$s herë. Përdorur së fundi %2$s më parë." "Lejo" "Lejo gjithmonë" "Lejo vetëm kur aplikacioni është në përdorim" @@ -103,15 +104,11 @@ "Autorizim te %1$s" "Qasje te %1$s për %2$s" "%1$s pati qasje te %2$s %3$s më parë." - - + "%1$s nuk ka pasur qasje te %2$s." "Shiko përdorimin e detajuar të autorizimeve" - - - - - - + "Qasja më e fundit %1$s më parë" + "Të lejuara" + "Të refuzuara" %s ditë 1 ditë @@ -136,36 +133,35 @@ - + "Zhvilluesi i aplikacionit thotë se të dhënat e tua mund:" + "Nëse nuk të pëlqen se si po i përdor të dhënat e tua ky zhvillues aplikacioni, mund ta refuzosh lejen." + "Të ngarkohen në renë kompjuterike" + "Të ngarkohen në renë kompjuterike kur lejohet qartësisht nga ty" + "Të ndahen me reklamuesit ose bizneset" + "Të ndahen me reklamuesit ose bizneset kur lejohet qartësisht nga ty" + "Të përdoren për fitim parash" + "Të përdoren për fitimin e parave kur lejohet qartësisht nga ty" + "Të ruhen dhe të analizohen përgjithmonë" + "Të ruhen dhe të analizohen për kohëzgjatjen e specifikuar nga ty" + + Të ruhen dhe të analizohen për %s javë + Të ruhen dhe të analizohen për 1 javë + + "Zhvilluesi i aplikacionit nuk ka specifikuar se si i përdor aplikacioni të dhënat e tua." + - + + + + + + "Aplikacionet e parazgjedhura" + "Asnjë aplikacion i parazgjedhur" + "Nuk ka aplikacione" "Aplikacioni \"Telefoni\"" "Aplikacioni për SMS" "Aplikacioni për shfletim" "Aplikacioni i galerisë" "Aplikacioni i muzikës" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml index 233411a26..b13cee91a 100644 --- a/res/values-sr/strings.xml +++ b/res/values-sr/strings.xml @@ -96,7 +96,8 @@ "Последњих 15 минута" "Дозволе нису коришћене" "Коришћење дозвола за аплик." - "пре %1$s" + "Приступ: %1$s пут(а). Укупно трајање: %2$s. Последњи пут коришћена пре %3$s." + "Приступ: %1$s пут(а). Последњи пут коришћена пре %2$s." "Дозволи" "Дозволи увек" "Дозволи само док се апликација користи" @@ -104,15 +105,11 @@ "Дозвола %1$s" "Приступ дозволи %1$s за апликацију %2$s" "Апликација %1$s је приступила дозволи %2$s пре %3$s." - - + "Апликација %1$s није приступила дозволи %2$s." "Прегледајте детаљне дозволе за коришћење" - - - - - - + "Најскорији приступ био је пре %1$s" + "Дозвољено" + "Одбијено" %s дан %s дана @@ -141,36 +138,36 @@ - + "Програмер апликације каже да подаци могу:" + "Ако вам се не свиђа како овај програмер апликације користи податке, можете да повучете дозволу." + "да се отпремају у клауд" + "да се отпремају у клауд када то изричито дозволите" + "да се деле са оглашавачима или предузећима" + "да се деле са оглашавачима или предузећима када то изричито дозволите" + "да се користе за монетизацију" + "да се користе за монетизацију када то изричито дозволите" + "да се чувају и анализирају заувек" + "да се чувају и анализирају у периоду који ви наведете" + + да се чувају и анализирају %s недељу + да се чувају и анализирају %s недеље + да се чувају и анализирају %s недеља + + "Програмер апликације није навео како апликација користи податке." + - + + + + + + "Подразумеване апликације" + "Нема подразумеване апликације." + "Нема апликација" "Апликација Телефон" "Апликација за SMS" "Апликација прегледача" "Апликација Галерија" "Апликација Музика" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml index 575d6e89f..98b991c62 100644 --- a/res/values-sv/strings.xml +++ b/res/values-sv/strings.xml @@ -95,7 +95,8 @@ "De senaste 15 minuterna" "Ingen behörighetsanvändning" "Appens behörighetsanvändning" - "För %1$s sedan" + "Åtkomst: %1$s gånger. Användningstid totalt: %2$s. Användes senast för %3$s sedan." + "Åtkomst: %1$s gånger. Användes senast för %2$s sedan." "Tillåt" "Tillåt alltid" "Tillåt bara när appen används" @@ -103,15 +104,11 @@ "Behörighet till %1$s" "Åtkomst till %1$s för %2$s" "%1$s använde din %2$s för %3$s sedan." - - + "%1$s har inte fått åtkomst till %2$s." "Visa utförlig information om behörighetsanvändning" - - - - - - + "Hade senast åtkomst för %1$s sedan" + "Tillåts" + "Nekas" %s dagar 1 dag @@ -136,36 +133,35 @@ - + "Enligt apputvecklaren kan din data" + "Om du inte gillar hur apputvecklaren använder din data kan du neka behörighet." + "laddas upp på molet" + "laddas upp på molnen när du tillåter det" + "delas med annonsörer eller företag" + "delas med annonsörer och företag när du tillåter det" + "användas till vinstgenerering" + "användas till vinstgenerering när du tillåter det" + "sparas och analyseras för alltid" + "sparas och analyseras under en tidsperiod som du anger" + + sparas och analyseras i %s veckor + sparas och analyseras i en vecka + + "Apputvecklaren har inte angett hur appen använder din data." + - + + + + + + "Standardappar" + "Inga standardappar" + "Inga appar" "Appen Telefon" "Sms-app" "Webbläsarapp" "Appen Galleri" "Appen Musik" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml index 20ce13ddb..074df969a 100644 --- a/res/values-sw/strings.xml +++ b/res/values-sw/strings.xml @@ -95,7 +95,8 @@ "Dakika 15 zilizopita" "Hakuna matumizi ya ruhusa" "Matumizi ya idhini za programu" - "%1$s zilizopita" + "Ufikiaji: mara %1$s. Jumla ya muda: %2$s. Mara ya mwisho ilitumika %3$s zilizopita." + "Ufikiaji: mara %1$s. Mara ya mwisho ilitumika %2$s zilizopita." "Ruhusu" "Ruhusu kila wakati" "Ruhusu tu wakati programu inatumika" @@ -103,15 +104,11 @@ "Ruhusa ya %1$s" "Ruhusa ya %1$s ya kufikia %2$s" "%1$s imefikia %2$s yako %3$s zilizopita." - - + "%1$s haijafikia %2$s yako." "Angalia matumizi ya ruhusa za kina" - - - - - - + "Ufikiaji wa hivi karibuni ulikuwa %1$s zilizopita" + "Zinazoruhusiwa" + "Imekataliwa" Siku %s Siku 1 @@ -136,36 +133,35 @@ - + "Msanidi wa programu anasema kuwa huenda data yako:" + "Kama hupendi jinsi msanidi wa programu anavyotumia data yako unaweza kukataa kumpa ruhusa." + "Itapakiwa kwenye wingu" + "Itapakiwa kwenye wingu unapotoa ruhusa bayana" + "Itashirikiwa na watangazaji au biashara" + "Itashirikiwa na watangazaji au biashara unapotoa ruhusa bayana" + "Inatumika katika uchumaji wa mapato" + "Itatumika katika uchumaji wa mapato unapotoa ruhusa bayana" + "Itahifadhiwa na kuchambuliwa milele" + "Itahifadhiwa na kuchambuliwa kwa kipindi utakachobainisha" + + Itahifadhiwa na kuchambuliwa kwa wiki %s + Itahifadhiwa na kuchambuliwa kwa wiki 1 + + "Msanidi wa programu hakubainisha jinsi programu inavyotumia data yako." + - + + + + + + "Programu chaguomsingi" + "Hakuna programu chaguomsingi" + "Hakuna programu" "Programu ya simu" "Programu ya SMS" "Programu ya kivinjari" "Programu ya matunzio" "Programu ya muziki" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml index afe5187a2..0ea60adc3 100644 --- a/res/values-ta/strings.xml +++ b/res/values-ta/strings.xml @@ -95,7 +95,8 @@ "கடந்த 15 நிமிடங்கள்" "உபயோகிக்கப்படாத அனுமதிகள்" "ஆப்ஸ் அனுமதிகளை உபயோகித்தல்" - "%1$s முன்பு" + "அணுகல்: %1$s முறை. மொத்தக் கால அளவு: %2$s. கடைசியாகப் பயன்படுத்தியது %3$s முன்பு." + "அணுகல்: %1$s முறை. கடைசியாகப் பயன்படுத்தியது %2$s முன்பு." "அனுமதி" "அனைத்து நேரங்களிலும் அனுமதி" "ஆப்ஸ் உபயோகத்தில் இருக்கும்போது மட்டும் அனுமதி" @@ -103,15 +104,11 @@ "%1$s என்பதற்கான அனுமதி" "%2$s ஆப்ஸிற்கான %1$s அணுகல்" "%3$s நேரத்திற்கு முன்பு %1$s ஆப்ஸ் உங்கள் %2$sஐ அணுகியது." - - + "%1$s உங்கள் %2$s அனுமதியைப் பயன்படுத்தவில்லை." "அனுமதிகளின் உபயோகம் தொடர்பான விவரங்களைக் காட்டு" - - - - - - + "மிகச் சமீபத்திய அணுகல்: %1$s முன்பு" + "அனுமதிக்கப்பட்டவை" + "மறுக்கப்பட்டது" %s நாட்கள் 1 நாள் @@ -136,36 +133,35 @@ - + "உங்கள் தரவிற்குப் பின்வருமாறு நேரலாம் என ஆப்ஸ் டெவெலப்பர் தெரிவிக்கிறார்:" + "தரவை ஆப்ஸ் டெவெலப்பர் பயன்படுத்தும் விதம் குறித்துத் தெரியவில்லை எனில் அனுமதியை நீங்கள் நிராகரிக்கலாம்." + "கிளவுடில் பதிவேற்றப்படும்" + "நீங்கள் வெளிப்படையாக அனுமதிக்கும்போது கிளவுடில் பதிவேற்றப்படும்" + "விளம்பரதாரர்களுடனோ வணிகங்களுடனோ பகிரப்படும்" + "நீங்கள் வெளிப்படையாக அனுமதிக்கும்போது விளம்பரதாரர்களுடனோ வணிகங்களுடனோ பகிரப்படும்" + "லாபம் பெறுவதற்குப் பயன்படுத்தப்படும்" + "நீங்கள் வெளிப்படையாக அனுமதிக்கும்போது லாபம் பெறுவதற்குப் பயன்படுத்தப்படும்" + "தரவு சேமிக்கப்பட்டு எப்போதும் பகுப்பாய்வு செய்யப்படும்" + "சேமிக்கப்பட்டு நீங்கள் குறிப்பிடும் காலத்திற்குப் பகுப்பாய்வு செய்யப்படும்" + + சேமிக்கப்பட்டு %s வாரங்களுக்குப் பகுப்பாய்வு செய்யப்படும் + சேமிக்கப்பட்டு 1 வாரத்திற்குப் பகுப்பாய்வு செய்யப்படும் + + "ஆப்ஸ் உங்கள் தரவை எவ்வாறு பயன்படுத்துகிறது என ஆப்ஸ் டெவெலப்பர் குறிப்பிடவில்லை." + - + + + + + + "இயல்புநிலை ஆப்ஸ்" + "இயல்புநிலை ஆப்ஸ் இல்லை" + "ஆப்ஸ் இல்லை" "மொபைல் ஆப்ஸ்" "மெசேஜ் ஆப்ஸ்" "உலாவி ஆப்ஸ்" "கேலரி ஆப்ஸ்" "மியூசிக் ஆப்ஸ்" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml index af2285e68..93fc4cc6b 100644 --- a/res/values-te/strings.xml +++ b/res/values-te/strings.xml @@ -95,7 +95,10 @@ "గత 15 నిమిషాలు" "అనుమతి వినియోగాలేవీ లేవు" "యాప్ అనుమతుల వినియోగం" - "%1$s క్రితం" + + + + "అనుమతించు" "అన్ని సమయాలలో అనుమతించు" "యాప్ వినియోగంలో ఉన్నప్పుడు మాత్రమే అనుమతించు" @@ -103,15 +106,11 @@ "%1$s అనుమతి" "%2$s కోసం %1$s యాక్సెస్" "%1$s మీ %2$sని %3$s క్రితం యాక్సెస్ చేసింది." - - + "%1$s మీ %2$sని ఉపయోగించలేదు." "వివరణాత్మక అనుమతుల వినియోగాన్ని చూడండి" - - - - - - + "తాజాగా %1$s క్రితం యాక్సెస్ చేసినది" + "అనుమతించినవి" + "తిరస్కరించినవి" %s రోజులు 1 రోజు @@ -136,36 +135,36 @@ - + "మీ డేటా ఏవిధంగా ఉపయోగించబడవచ్చు అనేది యాప్ డెవలపర్ చెప్తున్నారు:" + "ఈ యాప్ డెవలపర్ మీ డేటాని ఉపయోగించుకునే పద్ధతి మీకు నచ్చకపోతే నిశ్చింతగా అనుమతిని తిరస్కరించవచ్చు." + "క్లౌడ్‌లోకి అప్‌లోడ్ చేయబడుతుంది" + "మీరు స్పష్టంగా అనుమతించినప్పుడు, క్లౌడ్‌లోకి అప్‌లోడ్ చేయబడుతుంది" + "ప్రకటనదారులతో లేదా వ్యాపారాలతో షేర్ చేయబడుతుంది" + "మీరు స్పష్టంగా అనుమతించినప్పుడు, ప్రకటనదారులతో లేదా వ్యాపారాలతో షేర్ చేయబడుతుంది" + "డబ్బు ఆర్జన కోసం ఉపయోగించబడుతుంది" + "మీరు స్పష్టంగా అనుమతించినప్పుడు, డబ్బు ఆర్జన కోసం ఉపయోగించబడుతుంది" + "ఎల్లప్పుడూ సేవ్ చేసి, విశ్లేషిస్తుంది" + "మీరు నిర్దేశించిన సమయం వరకు సేవ్ చేసి, విశ్లేషిస్తుంది" + + %s వారాలలో సేవ్ చేసి, విశ్లేషించినది + 1 వారంలో సేవ్ చేసి, విశ్లేషించినది + + "యాప్ మీ డేటాని ఏవిధంగా ఉపయోగించుకుంటుంది అనేది యాప్ డెవలపర్‌ పేర్కొన‌లేదు." + + + + + - + + + "డిఫాల్ట్ యాప్‌లు" + "డిఫాల్ట్ యాప్‌లు ఏవీ లేవు" + "ఫోన్ యాప్" "SMS యాప్" "బ్రౌజర్ యాప్" "గ్యాలరీ యాప్‌" "సంగీత యాప్" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml index 54a260a14..423b7e060 100644 --- a/res/values-th/strings.xml +++ b/res/values-th/strings.xml @@ -95,7 +95,8 @@ "15 นาทีที่ผ่านมา" "ไม่มีการใช้สิทธิ์" "การใช้สิทธิ์ของแอป" - "%1$sที่ผ่านมา" + "เข้าถึง: %1$s ครั้ง ระยะเวลารวม: %2$s ใช้ล่าสุดเมื่อ %3$sที่ผ่านมา" + "เข้าถึง: %1$s ครั้ง ใช้ล่าสุดเมื่อ %2$sที่ผ่านมา" "อนุญาต" "อนุญาตตลอด" "อนุญาตเมื่อมีการใช้แอปเท่านั้น" @@ -103,15 +104,11 @@ "สิทธิ์เกี่ยวกับ%1$s" "สิทธิ์การเข้าถึง%1$sของ %2$s" "%1$s เข้าถึง%2$sของคุณเมื่อ %3$s ที่ผ่านมา" - - + "%1$s ไม่ได้เข้าถึง %2$s ของคุณ" "ดูรายละเอียดการใช้สิทธิ์" - - - - - - + "เข้าถึงล่าสุดเมื่อ %1$s ที่ผ่านมา" + "ได้รับอนุญาตแล้ว" + "ถูกปฏิเสธ" %s วัน 1 วัน @@ -136,36 +133,35 @@ - + "นักพัฒนาแอประบุว่าอาจมีการนำข้อมูลของคุณมาใช้ดังนี้" + "หากไม่ชอบวิธีที่นักพัฒนาแอปรายนี้ใช้ข้อมูลของคุณ คุณปฏิเสธสิทธิ์ได้" + "อัปโหลดไปยังระบบคลาวด์" + "อัปโหลดไปยังระบบคลาวด์ในกรณีที่คุณอนุญาตอย่างชัดเจน" + "แชร์กับผู้ลงโฆษณาหรือธุรกิจ" + "แชร์กับผู้ลงโฆษณาหรือธุรกิจในกรณีที่คุณอนุญาตอย่างชัดเจน" + "ใช้สำหรับการสร้างรายได้" + "ใช้สำหรับการสร้างรายได้ในกรณีที่คุณอนุญาตอย่างชัดเจน" + "บันทึกไว้และใช้วิเคราะห์ถาวร" + "บันทึกไว้และใช้วิเคราะห์ตามระยะเวลาที่คุณระบุ" + + บันทึกไว้และใช้วิเคราะห์เป็นเวลา %s สัปดาห์ + บันทึกไว้และใช้วิเคราะห์เป็นเวลา 1 สัปดาห์ + + "นักพัฒนาแอปไม่ได้ระบุว่าแอปจะใช้ข้อมูลของคุณอย่างไร" + - + + + + + + "แอปเริ่มต้น" + "ไม่มีแอปเริ่มต้น" + "ไม่มีแอป" "แอปโทรศัพท์" "แอป SMS" "แอปเบราว์เซอร์" "แอปแกลเลอรี" "แอปเพลง" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml index ccbae9165..1acedd618 100644 --- a/res/values-tl/strings.xml +++ b/res/values-tl/strings.xml @@ -95,7 +95,8 @@ "Nakalipas na 15 minuto" "Walang paggamit ng pahintulot" "Paggamit ng pahintulot sa app" - "%1$s na ang nakalipas" + "Na-access nang: %1$s (na) beses. Kabuuang tagal: %2$s. Huling ginamit %3$s ang nakalipas." + "Na-access nang: %1$s (na) beses. Huling ginamit %2$s ang nakalipas." "Payagan" "Payagan sa lahat ng oras" "Payagan lang habang ginagamit ang app" @@ -103,15 +104,11 @@ "%1$s na pahintulot" "%1$s na access para sa %2$s" "Na-access ng %1$s ang iyong %2$s %3$s ang nakalipas." - - + "Hindi na-access ng %1$s ang iyong %2$s." "Tingnan ang detalyadong paggamit sa mga pahintulot" - - - - - - + "Pinakakamakailang access, %1$s ang nakalipas" + "Pinapayagan" + "Tinanggihan" %s araw %s na araw @@ -136,36 +133,35 @@ - + "Ayon sa developer ng app, ang iyong data ay maaaring:" + "Kung hindi mo gusto kung paano ginagamit ng developer ng app na ito ang iyong data, maaari mong tanggihan ang pahintulot." + "I-upload sa cloud" + "I-upload sa cloud kapag tahasan mo itong pinayagan" + "Ibahagi sa mga advertiser o negosyo" + "Ibahagi sa mga advertiser o negosyo kapag tahasan mo itong pinayagan" + "Gamitin para sa monetization" + "Gamitin para sa monetization kapag tahasan mo itong pinayagan" + "I-save at suriin habambuhay" + "I-save at suriin sa loob ng tagal ng panahong tutukuyin mo" + + I-save at suriin sa loob ng %s (na) linggo + I-save at suriin sa loob ng %s (na) linggo + + "Hindi tinukoy ng developer ng app kung paano gagamitin ng app ang iyong data." + - + + + + + + "Mga default na app" + "Walang default na app" + "Walang app" "Phone app" "SMS app" "Browser app" "Gallery app" "Music app" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml index bb7386306..ec0cdd968 100644 --- a/res/values-tr/strings.xml +++ b/res/values-tr/strings.xml @@ -95,7 +95,8 @@ "Son 15 dakika" "İzin kullanılmadı" "Uygulama izinleri kullanımı" - "%1$s önce" + "Erişim: %1$s kez. Toplam süre: %2$s. En son %3$s önce kullanıldı." + "Erişim: %1$s kez. En son %2$s önce kullanıldı." "İzin ver" "Her zaman izin ver" "Yalnızca uygulama kullanılırken izin ver" @@ -103,15 +104,11 @@ "%1$s izni" "%2$s için %1$s erişimi" "%1$s %3$s önce cihazınızın %2$s özelliğine erişti." - - + "%1$s, %2$s izninize erişmedi." "Ayrıntılı izin kullanımını göster" - - - - - - + "En son erişim %1$s önce sağlandı" + "İzin verildi" + "Reddedildi" %s gün 1 gün @@ -136,36 +133,35 @@ - + "Uygulama geliştirici, verilerinizle ilgili şöyle söylüyor:" + "Bu uygulama geliştiricinin verilerinizi kullanma biçimini beğenmediyseniz izin vermeyebilirsiniz." + "Buluta yüklenir" + "Açık bir şekilde izin verdiğinizde buluta yüklenir" + "Reklamverenlerle veya işletmelerle paylaşılır" + "Açık bir şekilde izin verdiğinizde reklamverenlerle veya işletmelerle paylaşılır" + "Para kazanmak için kullanılır" + "Açık bir şekilde izin verdiğinizde para kazanmak için kullanılır" + "Sonsuza kadar saklanır ve analiz edilir" + "Belirttiğiniz süre boyunca saklanır ve analiz edilir" + + %s hafta boyunca saklanır ve analiz edilir + 1 hafta boyunca saklanır ve analiz edilir + + "Uygulama geliştirici, uygulamanın verilerinizi nasıl kullandığını belirtmedi." + - + + + + + + "Varsayılan uygulamalar" + "Varsayılan uygulama yok" + "Uygulama yok" "Telefon uygulaması" "SMS uygulaması" "Tarayıcı uygulaması" "Galeri uygulaması" "Müzik uygulaması" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml index 27962d4ff..0a59e3f19 100644 --- a/res/values-uk/strings.xml +++ b/res/values-uk/strings.xml @@ -97,7 +97,8 @@ "Останні 15 хвилин" "Дозволи не використовувалися" "Використання дозволів додатка" - "%1$s тому" + "Доступ: %1$s раз. Загальна тривалість: %2$s. Востаннє використано %3$s тому." + "Доступ: %1$s раз. Востаннє використано %2$s тому." "Дозволити" "Дозволяти завжди" "Дозволяти, лише коли додаток використовується" @@ -105,15 +106,11 @@ "Дозвіл – %1$s" "Доступ (%1$s) для додатка %2$s" "Додаток %1$s отримав доступ %3$s тому (%2$s)." - - + "%1$s не приймає дозвіл \"%2$s\"." "Переглянути детальну інформацію про використання дозволів" - - - - - - + "Востаннє отримано доступ %1$s тому" + "Дозволено" + "Відхилено" %s день %s дні @@ -146,36 +143,37 @@ - + "Розробник додатка вказує, що ваші дані можуть:" + "Якщо вам не подобається, як розробник додатка використовує ваші дані, можна скасувати дозвіл." + "завантажуватися в хмару" + "завантажуватися в хмару, коли ви це чітко дозволяєте" + "надаватися рекламодавцям або компаніям" + "надаватися рекламодавцям або компаніям, коли ви це чітко дозволяєте" + "Використовуються для монетизації" + "використовуватися для монетизації, коли ви це чітко дозволяєте" + "завжди зберігатися й аналізуватися" + "Зберігаються й аналізуються протягом указаного вами періоду часу" + + Зберігаються й аналізуються %s тиждень + Зберігаються й аналізуються %s тижні + Зберігаються й аналізуються %s тижнів + Зберігаються й аналізуються %s тижня + + "Розробник додатка не вказує, як використовуються ваші дані." + - + + + + + + "Додатки за умовчанням" + "Немає додатків за умовчанням" + "Немає додатків" "Додаток Телефон" "Додаток для SMS" "Додаток для веб-перегляду" "Додаток Галерея" "Додаток Музика" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml index 69a2f0739..ee465d4e5 100644 --- a/res/values-ur/strings.xml +++ b/res/values-ur/strings.xml @@ -95,7 +95,10 @@ "آخری 15 منٹ" "اجازت کا استعمال نہیں ہوا ہے" "ایپ کی اجازتوں کا استعمال" - "%1$s پہلے" + + + + "اجازت دیں" "ہر وقت اجازت دیں" "صرف اسی وقت اجازت دیں جب ایپ استعمال کی جا رہی ہو" @@ -103,15 +106,11 @@ "%1$s کی اجازت" "%1$s نے %2$s کیلئے رسائی حاصل کی" "%1$s نے %3$s پہلے %2$s تک رسائی حاصل کی۔" - - + "%1$s نے آپ کے %2$s تک رسائی نہیں کی ہے۔" "تفصیلی اجازتوں کا استعمال دیکھیں" - - - - - - + "حالیہ ترین رسائی %1$s پہلے" + "اجازت ہے" + "مسترد ہو گئی" %s دن 1 دن @@ -136,36 +135,36 @@ - + "ایپ ڈیولپر کے مطابق آپ کا ڈیٹا ایسا ہو سکتا ہے:" + "اگر آپ کو اس ایپ ڈیولپر کے آپ کا ڈیٹا استعمال کرنے کا طریقہ پسند نہیں ہے تو آپ اجازت کو مسترد کر سکتے ہیں۔" + "کلاؤڈ میں اپ لوڈ کیا گیا" + "آپ کی جانب سے صَرِيح طور پر اپ لوڈ کی اجازت دیے جانے کے وقت کلاؤڈ میں اپ لوڈ کیا گیا" + "مشتہرین یا کاروباروں کے ساتھ اشتراک کیا گیا" + "آپ کی جانب سے صَرِيح طور پر اشتراک کی اجازت دیے جانے کے وقت مشتہرین یا کاروباروں کے ساتھ اشتراک کیا گیا" + "منیٹائزیشن کیلئے استعمال کیا گیا" + "آپ کی جانب سے صَرِيح طور پر منیٹائزیشن کی اجازت دیے جانے کے وقت اس مقصد کیلئے استعمال کیا گیا" + "ہمیشہ کیلئے محفوظ کیا گیا اور تجزیہ کیا گیا" + "آپ کے وضاحت کردہ دورانیے کیلئے محفوظ اور تجزیہ کیا گیا" + + %s ہفتوں کیلئے محفوظ اور تجزیہ کیا گیا + 1 ہفتے کیلئے محفوظ اور تجزیہ کیا گیا + + "ایپ ڈیولپر نے اس بات کی وضاحت نہیں کی کہ ایپ کیسے آپ کا ڈیٹا استعمال کرتی ہے۔" + + + + + - + + + "ڈیفالٹ ایپس" + "کوئی ڈیفالٹ ایپ نہیں ہے" + "فون ایپ" "‏SMS ایپ" "براؤزر ایپ" "گیلری ایپ" "موسیقی ایپ" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml index fb1e4c236..0b9fc2e3b 100644 --- a/res/values-uz/strings.xml +++ b/res/values-uz/strings.xml @@ -95,7 +95,8 @@ "Oxirgi 15 daqiqa" "Ruxsatlardan foydalanilmagan" "Ilovalar uchun ruxsatlar" - "%1$s oldin" + "Kirish talabi: %1$s marta. Jami foydalanish vaqti: %2$s. Oxirgi marta %3$s oldin foydalanilgan." + "Kirish talabi: %1$s marta. Oxirgi marta %2$s oldin foydalanilgan." "Ruxsat berish" "Har qanday rejimda ruxsat berish" "Faqat faol rejimda ruxsat berish" @@ -103,15 +104,11 @@ "%1$s ruxsati" "%2$s uchun %1$s ruxsati" "%1$s %3$s oldin %2$s ruxsatidan foydalandi." - - + "%1$s ilovasi uchun %2$s ruxsati berilmagan." "Ruxsatlardan foydalanish haqida batafsil axborotni ochish" - - - - - - + "Oxirgi ruxsat: %1$s oldin" + "Taqdim etilgan ruxsat" + "Taqdim etilmagan ruxsatlar" %s kun 1 kun @@ -136,36 +133,35 @@ - + "Ilova ishlab chiquvchisiga koʻra, maʼlumotlaringiz quyidagi maqsadlarda ishlatilishi mumkin:" + "Agar ilova ishlab chiquvchisi maʼlumotlaringizdan qay tarzda foydalanishiga rozi boʻlmasangiz, ruxsat bermang." + "Bulutdagi xotiraga yuklash" + "Sizning mutloq roziligingiz bilan bulutdagi xotiraga yuklash" + "Reklama beruvchilar va tijoriy kompaniyalarga taqdim etish" + "Sizning mutloq roziligingiz bilan reklama beruvchilar va tijoriy kompaniyalarga taqdim etish" + "Tijoriy maqsadlarda foydalanish" + "Sizning mutloq roziligingiz bilan tijoriy maqsadlarda foydalanish" + "Cheklanmagan vaqtda tahlil uchun saqlash va foydalanish" + "Muayyan vaqt davomida tahlil uchun saqlash va foydalanish" + + %s hafta davomida tahlil uchun saqlash va foydalanish + 1 hafta davomida tahlil uchun saqlash va foydalanish + + "Ilova ishlab chiquvchisi maʼlumotlaringizda ilova qanday foydalanishini bildirmagan." + - + + + + + + "Birlamchi ilovalar" + "Birlamchi ilovalar mavjud emas" + "Hech qanday ilova topilmadi" "Telefon ilovasi" "SMS ilovasi" "Brauzer ilovasi" "Galereya ilovasi" "Musiqa ilovasi" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml index 9cc4803d3..f0807eb69 100644 --- a/res/values-vi/strings.xml +++ b/res/values-vi/strings.xml @@ -95,7 +95,8 @@ "15 phút trước" "Không sử dụng quyền" "Sử dụng quyền ứng dụng" - "%1$s trước" + "Truy cập: %1$s lần. Tổng thời gian: %2$s. Sử dụng lần gần đây nhất vào %3$s trước." + "Truy cập: %1$s lần. Sử dụng lần gần đây nhất vào %2$s trước." "Cho phép" "Luôn cho phép" "Chỉ cho phép khi đang sử dụng ứng dụng" @@ -103,15 +104,11 @@ "Quyền %1$s" "Quyền truy cập vào %1$s của %2$s" "%1$s đã truy cập vào %2$s %3$s trước." - - + "%1$s chưa truy cập vào %2$s của bạn." "Xem mức sử dụng quyền chi tiết" - - - - - - + "Lần truy cập gần đây nhất vào %1$s trước" + "Được phép" + "Bị từ chối" %s ngày 1 ngày @@ -136,36 +133,35 @@ - + "Nhà phát triển ứng dụng cho biết dữ liệu của bạn có thể được:" + "Nếu không thích cách nhà phát triển ứng dụng này sử dụng dữ liệu của mình, thì bạn có thể từ chối cấp quyền." + "Tải lên đám mây" + "Tải lên đám mây khi bạn cho phép rõ ràng" + "Chia sẻ với các nhà quảng cáo hoặc doanh nghiệp" + "Chia sẻ với các nhà quảng cáo hoặc doanh nghiệp khi bạn cho phép rõ ràng" + "Dùng để kiếm tiền" + "Dùng để kiếm tiền khi bạn cho phép rõ ràng" + "Lưu và phân tích vĩnh viễn" + "Lưu và phân tích trong thời gian bạn chỉ định" + + Lưu và phân tích trong %s tuần + Lưu và phân tích trong 1 tuần + + "Nhà phát triển ứng dụng không chỉ rõ cách ứng dụng sử dụng dữ liệu của bạn." + - + + + + + + "Ứng dụng mặc định" + "Không có ứng dụng mặc định" + "Không có ứng dụng" "Ứng dụng điện thoại" "Ứng dụng SMS" "Ứng dụng trình duyệt" "Ứng dụng thư viện" "Ứng dụng âm nhạc" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml index e94da0e14..9196a38df 100644 --- a/res/values-zh-rCN/strings.xml +++ b/res/values-zh-rCN/strings.xml @@ -95,7 +95,8 @@ "过去 15 分钟" "没有使用此权限的应用" "应用权限使用情况" - "%1$s前" + "访问次数:%1$s 次。总时长:%2$s。上次使用时间:%3$s前。" + "访问次数:%1$s 次。上次使用时间:%2$s前。" "允许" "始终允许" "仅在使用该应用期间允许" @@ -103,15 +104,11 @@ "%1$s权限" "%2$s%1$s访问权限" "%1$s %3$s前访问过您的%2$s。" - - + "%1$s尚未取得您的%2$s访问权限。" "查看权限使用情况详情" - - - - - - + "最近访问时间:%1$s前" + "已允许" + "已拒绝" %s 1 天 @@ -136,36 +133,35 @@ - + "应用开发者表示可能会将您的数据:" + "如果您对此应用开发者使用您数据的方式不满,可以拒绝授予权限。" + "上传到云端" + "在获得您明确授权后将数据上传到云端" + "与广告客户或商家分享您的数据" + "在获得您明确授权后与广告客户或商家分享您的数据" + "用于盈利" + "在获得您明确授权后将数据用于盈利" + "无限期保存及分析数据" + "保存及进行分析(在您指定的时间内)" + + 保存及进行分析(在 %s 周内) + 保存及进行分析(在 1 周内) + + "应用开发者未指定这个应用使用您数据的方式。" + - + + + + + + "默认应用" + "没有任何默认应用" + "没有应用" "电话应用" "短信应用" "浏览器应用" "图库应用" "音乐应用" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml index 377eeaed4..82e3c5f20 100644 --- a/res/values-zh-rHK/strings.xml +++ b/res/values-zh-rHK/strings.xml @@ -95,7 +95,8 @@ "過去 15 分鐘" "沒有應用程式使用要求的權限" "應用程式權限使用情況" - "%1$s前" + "存取次數:%1$s 次。總時長:%2$s。上次使用時間:%3$s前。" + "存取次數:%1$s 次。上次使用時間:%2$s前。" "允許" "一律允許" "只在使用應用程式時允許" @@ -103,15 +104,11 @@ "%1$s權限" "「%2$s」的%1$s存取權" "「%1$s」在 %3$s前存取了您的%2$s。" - - + "「%1$s」沒有存取%2$s。" "查看詳細的權限使用情況" - - - - - - + "最近存取時間:%1$s之前" + "已允許" + "已拒絕" %s 1 天 @@ -136,36 +133,35 @@ - + "應用程式開發人員表示您的資料可能:" + "如果您不喜歡應用程式開發人員使用資料的方式,則可拒絕授予權限。" + "已上載至雲端" + "已在您明確同意的情況下上載至雲端" + "已與廣告客戶或商家分享" + "已在您明確同意的情況下,與廣告客戶或商家分享" + "已用於營利" + "已在您明確同意的情況下用於營利" + "已永久儲存和分析" + "已在您指定的時段儲存和分析" + + 已儲存和分析 %s 星期 + 已儲存和分析 1 星期 + + "應用程式開發人員沒有註明應用程式如何使用您的資料。" + - + + + + + + "預設應用程式" + "沒有預設應用程式" + "沒有應用程式" "手機應用程式" "短訊應用程式" "瀏覽器應用程式" "相片集應用程式" "音樂應用程式" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml index 545037d80..2626485e7 100644 --- a/res/values-zh-rTW/strings.xml +++ b/res/values-zh-rTW/strings.xml @@ -95,7 +95,8 @@ "過去 15 分鐘" "沒有使用此權限的應用程式" "應用程式權限使用情況" - "%1$s前" + "使用次數:%1$s 次。總時間長度:%2$s。上次使用時間:%3$s前。" + "使用次數:%1$s 次。上次使用時間:%2$s前。" "允許" "一律允許" "僅在使用該應用程式時允許" @@ -103,15 +104,11 @@ "%1$s權限" "「%2$s」的%1$s存取權" "「%1$s」在 %3$s前存取了你的%2$s。" - - + "「%1$s」尚未取得你的%2$s存取權。" "查看詳細的權限使用情況" - - - - - - + "上次存取時間:%1$s前" + "已允許" + "已拒絕" %s 1 天 @@ -136,36 +133,35 @@ - + "應用程式開發人員可能會將你的資料:" + "如果你對應用程式開發人員使用資料的方式不滿意,可以拒絕授予權限。" + "上傳到雲端" + "上傳到雲端 (當你明確允許時)" + "與廣告客戶或商家分享" + "與廣告客戶或商家分享 (當你明確允許時)" + "用於營利" + "用於營利 (當你明確允許時)" + "儲存並用於分析 (永久)" + "儲存並用於分析 (在你指定的時間內)" + + 儲存並用於分析 (%s 週) + 儲存並用於分析 (1 週) + + "應用程式開發人員並未指定這個應用程式如何使用你的資料。" + - + + + + + + "預設應用程式" + "沒有任何預設應用程式" + "沒有應用程式" "「電話」應用程式" "簡訊應用程式" "瀏覽器應用程式" "圖片庫應用程式" "音樂應用程式" - - - - - - - - - - - - - - - - - - - - - - - diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml index 21728a2d8..39a48b57f 100644 --- a/res/values-zu/strings.xml +++ b/res/values-zu/strings.xml @@ -95,7 +95,8 @@ "Amaminithi angu-15 okugcina" "Akukho ukusetshenziswa kwemvume" "Ukusetshenziswa kwezimvume zohlelo lokusebenza" - "%1$s edlule" + "Ukufinyelela: %1$s izikhathi. Ubude besikhathi: %2$s. Kugcinwe ukusetshenziswa u-%3$s owedlule." + "Ukufinyelela: %1$s izikhathi. Kugcinwe ukusetshenziswa u-%2$s odlule." "Vumela" "Vumela sonke isikhathi" "Vumela kuphela ngenkathi uhlelo lokusebenza lusebenza" @@ -103,15 +104,11 @@ "%1$s imvume" "%1$s ukufinyelela kwe-%2$s" "%1$s ufinyelele u-%2$s yakho isikhathi esingu-%3$s esedlule." - - + "%1$s ayifinyelele i-%2$s yakho." "Buka ukusetshenziswa kwezimvume ezinemininingwane" - - - - - - + "Ukufinyelela kwakamuva kakhulu u-%1$s" + "Kuvumelekile" + "Kunqatshiwe" %s izinsuku %s izinsuku @@ -136,36 +133,35 @@ - + "Unjiniyela wohlelo lokusebenza uthi idatha yakho ingaba:" + "Uma ungathandi indlela unjiniyela walolu hlelo lokusebenza asebenzisa ngayo idatha yakho unganqabela imvume." + "Kulayishwe emafini" + "Kulayishwe emafini uma ukuvumela ngokucacile" + "Kwabiwe nabakhangisi noma amabhizinisi" + "Kwabiwe nabakhangisi noma amabhizinisi uma ukuvumela ngokucacile" + "Kusetshenziselwa ukwenza imali" + "Kusetshenziselwa ukwenza imali uma ukuvumela ngokucacile" + "Kulondolozwe futhi kwahlaziywa unaphakade" + "Kulondolozwe futhi kwahlaziyelwa ubude obucacisile" + + Kulondoloziwe futhi kwahlaziyelwa amaviki angu-%s + Kulondoloziwe futhi kwahlaziyelwa amaviki angu-%s + + "Unjiniyela wohlelo lokusebenza akacacisanga indlela uhlelo lokusebenza lisebenzisa idatha yakho." + - + + + + + + "Izinhlelo zokusebenza ezizenzakalelayo" + "Azikho izinhlelo zokusebenza ezizenzakalelayo" + "Azikho izinhlelo zokusebenza" "Uhlelo lokusebenza lwefoni" "Uhlelo lokusebenza lwe-SMS" "Uhlelo lokusebenza lwesiphequluli" "Uhlelo lokusebenza lwegalari" "Uhlelo lokusebenza lomculo" - - - - - - - - - - - - - - - - - - - - - - - -- GitLab From 6538664440d72e44a436147121adee52d256c855 Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Fri, 7 Dec 2018 14:50:06 -0800 Subject: [PATCH 191/701] Use OnRoleHoldersChangedListener for default apps UI. This change uses OnRoleHoldersChangedListener for updating the state of default apps UI. Bug: 110557011 Test: manual Change-Id: Ibbd8c4d89d6515217d2ee9d742ccdce4d79b906d --- AndroidManifest.xml | 1 + .../packageinstaller/role/model/Role.java | 2 +- .../service/RoleControllerServiceImpl.java | 4 +++ .../role/ui/DefaultAppFragment.java | 5 +--- .../role/ui/RoleListLiveData.java | 26 ++++++++++++++++++- .../role/ui/RoleLiveData.java | 26 ++++++++++++++++++- 6 files changed, 57 insertions(+), 7 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index ba845e84f..bc1eae2c3 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -26,6 +26,7 @@ + diff --git a/src/com/android/packageinstaller/role/model/Role.java b/src/com/android/packageinstaller/role/model/Role.java index 7f48e2b9e..9527d0eed 100644 --- a/src/com/android/packageinstaller/role/model/Role.java +++ b/src/com/android/packageinstaller/role/model/Role.java @@ -247,7 +247,7 @@ public class Role { } /** - * Revoke this role to an application. + * Revoke this role from an application. * * @param packageName the package name of the application to be granted this role to * @param mayKillApp whether this application may be killed due to changes diff --git a/src/com/android/packageinstaller/role/service/RoleControllerServiceImpl.java b/src/com/android/packageinstaller/role/service/RoleControllerServiceImpl.java index b4a2c394a..f96b24ae0 100644 --- a/src/com/android/packageinstaller/role/service/RoleControllerServiceImpl.java +++ b/src/com/android/packageinstaller/role/service/RoleControllerServiceImpl.java @@ -124,6 +124,10 @@ public class RoleControllerServiceImpl extends RoleControllerService { @Override public void onGrantDefaultRoles(@NonNull RoleManagerCallback callback) { + if (callback == null) { + Log.e(LOG_TAG, "callback cannot be null"); + return; + } ArrayMap roles = Roles.getRoles(this); // TODO: Clean up holders of roles that will be removed. List roleNames = new ArrayList<>(roles.keySet()); diff --git a/src/com/android/packageinstaller/role/ui/DefaultAppFragment.java b/src/com/android/packageinstaller/role/ui/DefaultAppFragment.java index a7215cbb6..a9edd6e7e 100644 --- a/src/com/android/packageinstaller/role/ui/DefaultAppFragment.java +++ b/src/com/android/packageinstaller/role/ui/DefaultAppFragment.java @@ -165,15 +165,12 @@ public class DefaultAppFragment extends SettingsFragment public void onSuccess() { Log.i(LOG_TAG, "Added application as role holder, role: " + mRoleName + ", package: " + packageName); - // TODO: STOPSHIP: Use role holder observation instead. - mViewModel.getLiveData().loadValue(); } @Override public void onFailure() { Log.i(LOG_TAG, "Failed to add application as role holder, role: " + mRoleName + ", package: " + packageName); - // TODO: STOPSHIP: Use role holder observation instead. - mViewModel.getLiveData().loadValue(); + // TODO: STOPSHIP: Notify user. } }); return true; diff --git a/src/com/android/packageinstaller/role/ui/RoleListLiveData.java b/src/com/android/packageinstaller/role/ui/RoleListLiveData.java index af2275391..78d33b2c7 100644 --- a/src/com/android/packageinstaller/role/ui/RoleListLiveData.java +++ b/src/com/android/packageinstaller/role/ui/RoleListLiveData.java @@ -16,9 +16,12 @@ package com.android.packageinstaller.role.ui; +import android.app.role.OnRoleHoldersChangedListener; import android.app.role.RoleManager; import android.content.Context; import android.content.pm.ApplicationInfo; +import android.os.Process; +import android.os.UserHandle; import android.util.ArrayMap; import android.util.Log; @@ -36,7 +39,8 @@ import java.util.List; /** * {@link LiveData} for a list of roles. */ -public class RoleListLiveData extends AsyncTaskLiveData> { +public class RoleListLiveData extends AsyncTaskLiveData> + implements OnRoleHoldersChangedListener { private static final String LOG_TAG = RoleListLiveData.class.getSimpleName(); @@ -46,7 +50,27 @@ public class RoleListLiveData extends AsyncTaskLiveData> { public RoleListLiveData(boolean exclusive, @NonNull Context context) { mExclusive = exclusive; mContext = context; + } + + @Override + protected void onActive() { + loadValue(); + + RoleManager roleManager = mContext.getSystemService(RoleManager.class); + // TODO: STOPSHIP: Handle work profile? + roleManager.addOnRoleHoldersChangedListenerAsUser(mContext.getMainExecutor(), this, + Process.myUserHandle()); + } + + @Override + protected void onInactive() { + RoleManager roleManager = mContext.getSystemService(RoleManager.class); + // TODO: STOPSHIP: Handle work profile? + roleManager.removeOnRoleHoldersChangedListenerAsUser(this, Process.myUserHandle()); + } + @Override + public void onRoleHoldersChanged(@NonNull String roleName, @NonNull UserHandle user) { loadValue(); } diff --git a/src/com/android/packageinstaller/role/ui/RoleLiveData.java b/src/com/android/packageinstaller/role/ui/RoleLiveData.java index 02b62e288..2b1117df5 100644 --- a/src/com/android/packageinstaller/role/ui/RoleLiveData.java +++ b/src/com/android/packageinstaller/role/ui/RoleLiveData.java @@ -16,9 +16,12 @@ package com.android.packageinstaller.role.ui; +import android.app.role.OnRoleHoldersChangedListener; import android.app.role.RoleManager; import android.content.Context; import android.content.pm.ApplicationInfo; +import android.os.Process; +import android.os.UserHandle; import android.util.Log; import androidx.annotation.NonNull; @@ -34,7 +37,8 @@ import java.util.List; /** * {@link LiveData} for a role. */ -public class RoleLiveData extends AsyncTaskLiveData { +public class RoleLiveData extends AsyncTaskLiveData + implements OnRoleHoldersChangedListener { private static final String LOG_TAG = RoleLiveData.class.getSimpleName(); @@ -44,7 +48,27 @@ public class RoleLiveData extends AsyncTaskLiveData { public RoleLiveData(@NonNull Role role, @NonNull Context context) { mRole = role; mContext = context; + } + + @Override + protected void onActive() { + loadValue(); + + RoleManager roleManager = mContext.getSystemService(RoleManager.class); + // TODO: STOPSHIP: Handle work profile? + roleManager.addOnRoleHoldersChangedListenerAsUser(mContext.getMainExecutor(), this, + Process.myUserHandle()); + } + + @Override + protected void onInactive() { + RoleManager roleManager = mContext.getSystemService(RoleManager.class); + // TODO: STOPSHIP: Handle work profile? + roleManager.removeOnRoleHoldersChangedListenerAsUser(this, Process.myUserHandle()); + } + @Override + public void onRoleHoldersChanged(@NonNull String roleName, @NonNull UserHandle user) { loadValue(); } -- GitLab From ef5a3d26fbe10e98be684c723743c7eb351ffa8f Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Fri, 7 Dec 2018 16:01:14 -0800 Subject: [PATCH 192/701] Use LiveData to track the state of adding a role holder. This change uses LiveData to track the state of adding a role holder, so that we can handle user clicking too fast properly. Bug: 110557011 Test: manual Change-Id: Icbd66ed87fb9aa512cdc98bbc106e2926cdc6ade --- ...a.java => AddRoleHolderStateLiveData.java} | 26 ++++++--- .../role/ui/DefaultAppFragment.java | 53 ++++++++++--------- ...iewModel.java => DefaultAppViewModel.java} | 27 ++++++---- .../role/ui/RequestRoleFragment.java | 14 ++--- .../role/ui/RequestRoleViewModel.java | 4 +- 5 files changed, 74 insertions(+), 50 deletions(-) rename src/com/android/packageinstaller/role/ui/{RequestRoleLiveData.java => AddRoleHolderStateLiveData.java} (76%) rename src/com/android/packageinstaller/role/ui/{RoleViewModel.java => DefaultAppViewModel.java} (65%) diff --git a/src/com/android/packageinstaller/role/ui/RequestRoleLiveData.java b/src/com/android/packageinstaller/role/ui/AddRoleHolderStateLiveData.java similarity index 76% rename from src/com/android/packageinstaller/role/ui/RequestRoleLiveData.java rename to src/com/android/packageinstaller/role/ui/AddRoleHolderStateLiveData.java index 564a064af..45c0e8061 100644 --- a/src/com/android/packageinstaller/role/ui/RequestRoleLiveData.java +++ b/src/com/android/packageinstaller/role/ui/AddRoleHolderStateLiveData.java @@ -29,24 +29,24 @@ import androidx.lifecycle.LiveData; import java.util.concurrent.Executor; /** - * {@link LiveData} for the state of a role request. + * {@link LiveData} for the state of adding a role holder. */ -public class RequestRoleLiveData extends LiveData { +public class AddRoleHolderStateLiveData extends LiveData { - private static final String LOG_TAG = RequestRoleLiveData.class.getSimpleName(); + private static final String LOG_TAG = AddRoleHolderStateLiveData.class.getSimpleName(); public static final int STATE_IDLE = 0; public static final int STATE_ADDING = 1; public static final int STATE_SUCCESS = 2; public static final int STATE_FAILURE = 3; - public RequestRoleLiveData() { + public AddRoleHolderStateLiveData() { setValue(STATE_IDLE); } /** * Add an application to the holders of a role, and update the state accordingly. Will be no-op - * if already called once. + * if the current state is not {@link #STATE_IDLE}. * * @param roleName the name of the role * @param packageName the package name of the application @@ -55,7 +55,7 @@ public class RequestRoleLiveData extends LiveData { public void addRoleHolder(@NonNull String roleName, @NonNull String packageName, @NonNull Context context) { if (getValue() != STATE_IDLE) { - Log.w(LOG_TAG, "Already (tried) adding package as role holder, requested role: " + Log.e(LOG_TAG, "Already (tried) adding package as role holder, requested role: " + roleName + ", requested package: " + packageName); return; } @@ -82,4 +82,18 @@ public class RequestRoleLiveData extends LiveData { } }); } + + /** + * Reset the state of this live data to {@link #STATE_IDLE}. Will be no-op if the current state + * is not {@link #STATE_SUCCESS} or {@link #STATE_FAILURE}. + */ + public void resetState() { + int state = getValue(); + if (!(state == STATE_SUCCESS || state == STATE_FAILURE)) { + Log.e(LOG_TAG, "Trying to reset state when the current state is not STATE_SUCCESS or" + + " STATE_FAILURE"); + return; + } + setValue(STATE_IDLE); + } } diff --git a/src/com/android/packageinstaller/role/ui/DefaultAppFragment.java b/src/com/android/packageinstaller/role/ui/DefaultAppFragment.java index a9edd6e7e..5a49488a7 100644 --- a/src/com/android/packageinstaller/role/ui/DefaultAppFragment.java +++ b/src/com/android/packageinstaller/role/ui/DefaultAppFragment.java @@ -17,12 +17,9 @@ package com.android.packageinstaller.role.ui; import android.app.Activity; -import android.app.role.RoleManager; -import android.app.role.RoleManagerCallback; import android.content.Context; import android.content.pm.ApplicationInfo; import android.os.Bundle; -import android.os.Process; import android.os.UserHandle; import android.util.ArrayMap; import android.util.Log; @@ -59,7 +56,7 @@ public class DefaultAppFragment extends SettingsFragment private Role mRole; - private RoleViewModel mViewModel; + private DefaultAppViewModel mViewModel; /** * Create a new instance of this fragment. @@ -92,9 +89,10 @@ public class DefaultAppFragment extends SettingsFragment mRole = Roles.getRoles(activity).get(mRoleName); activity.setTitle(mRole.getLabelResource()); - mViewModel = ViewModelProviders.of(this, new RoleViewModel.Factory(mRole, - activity.getApplication())).get(RoleViewModel.class); - mViewModel.getLiveData().observe(this, this::onRoleInfoChanged); + mViewModel = ViewModelProviders.of(this, new DefaultAppViewModel.Factory(mRole, + activity.getApplication())).get(DefaultAppViewModel.class); + mViewModel.getRoleLiveData().observe(this, this::onRoleInfoChanged); + mViewModel.getAddRoleHolderStateLiveData().observe(this, this::onAddRoleHolderStateChanged); } @Override @@ -151,28 +149,31 @@ public class DefaultAppFragment extends SettingsFragment updateState(); } + private void onAddRoleHolderStateChanged(int state) { + AddRoleHolderStateLiveData addRoleHolderStateLiveData = + mViewModel.getAddRoleHolderStateLiveData(); + switch (state) { + case AddRoleHolderStateLiveData.STATE_SUCCESS: + addRoleHolderStateLiveData.resetState(); + break; + case AddRoleHolderStateLiveData.STATE_FAILURE: + // TODO: STOPSHIP: Notify user. + addRoleHolderStateLiveData.resetState(); + break; + } + } + @Override public boolean onPreferenceClick(@NonNull Preference preference) { - // TODO: STOPSHIP: Support multiple role holders. + AddRoleHolderStateLiveData addRoleHolderStateLiveData = + mViewModel.getAddRoleHolderStateLiveData(); + if (addRoleHolderStateLiveData.getValue() != AddRoleHolderStateLiveData.STATE_IDLE) { + Log.i(LOG_TAG, "Trying to set default app while another request is on-going"); + return true; + } + String packageName = preference.getKey(); - Log.i(LOG_TAG, "Adding application as role holder, role: " + mRoleName + ", package: " - + packageName); - Context context = requireContext(); - RoleManager roleManager = context.getSystemService(RoleManager.class); - roleManager.addRoleHolderAsUser(mRoleName, packageName, Process.myUserHandle(), - context.getMainExecutor(), new RoleManagerCallback() { - @Override - public void onSuccess() { - Log.i(LOG_TAG, "Added application as role holder, role: " + mRoleName - + ", package: " + packageName); - } - @Override - public void onFailure() { - Log.i(LOG_TAG, "Failed to add application as role holder, role: " - + mRoleName + ", package: " + packageName); - // TODO: STOPSHIP: Notify user. - } - }); + addRoleHolderStateLiveData.addRoleHolder(mRoleName, packageName, requireContext()); return true; } } diff --git a/src/com/android/packageinstaller/role/ui/RoleViewModel.java b/src/com/android/packageinstaller/role/ui/DefaultAppViewModel.java similarity index 65% rename from src/com/android/packageinstaller/role/ui/RoleViewModel.java rename to src/com/android/packageinstaller/role/ui/DefaultAppViewModel.java index 0f25cfd08..163327aa7 100644 --- a/src/com/android/packageinstaller/role/ui/RoleViewModel.java +++ b/src/com/android/packageinstaller/role/ui/DefaultAppViewModel.java @@ -26,26 +26,35 @@ import androidx.lifecycle.ViewModelProvider; import com.android.packageinstaller.role.model.Role; /** - * {@link ViewModel} for a role. + * {@link ViewModel} for a default app. */ -public class RoleViewModel extends AndroidViewModel { +public class DefaultAppViewModel extends AndroidViewModel { @NonNull - private final RoleLiveData mLiveData; + private final RoleLiveData mRoleLiveData; - public RoleViewModel(@NonNull Role role, @NonNull Application application) { + @NonNull + private final AddRoleHolderStateLiveData mAddRoleHolderStateLiveData = + new AddRoleHolderStateLiveData(); + + public DefaultAppViewModel(@NonNull Role role, @NonNull Application application) { super(application); - mLiveData = new RoleLiveData(role, application); + mRoleLiveData = new RoleLiveData(role, application); + } + + @NonNull + public RoleLiveData getRoleLiveData() { + return mRoleLiveData; } @NonNull - public RoleLiveData getLiveData() { - return mLiveData; + public AddRoleHolderStateLiveData getAddRoleHolderStateLiveData() { + return mAddRoleHolderStateLiveData; } /** - * {@link ViewModelProvider.Factory} for {@link RoleViewModel}. + * {@link ViewModelProvider.Factory} for {@link DefaultAppViewModel}. */ public static class Factory implements ViewModelProvider.Factory { @@ -64,7 +73,7 @@ public class RoleViewModel extends AndroidViewModel { @Override public T create(@NonNull Class modelClass) { //noinspection unchecked - return (T) new RoleViewModel(mRole, mApplication); + return (T) new DefaultAppViewModel(mRole, mApplication); } } } diff --git a/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java b/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java index 39bff854e..c9ed25090 100644 --- a/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java +++ b/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java @@ -140,7 +140,7 @@ public class RequestRoleFragment extends DialogFragment { super.onActivityCreated(savedInstanceState); mViewModel = ViewModelProviders.of(this).get(RequestRoleViewModel.class); - mViewModel.getLiveData().observe(this, this::onRequestRoleStateChanged); + mViewModel.getLiveData().observe(this, this::onAddRoleHolderStateChanged); } @Override @@ -176,7 +176,7 @@ public class RequestRoleFragment extends DialogFragment { } @Override - public void onDismiss(DialogInterface dialog) { + public void onDismiss(@NonNull DialogInterface dialog) { super.onDismiss(dialog); Log.i(LOG_TAG, "Dialog dismissed, role: " + mRoleName + ", package: " @@ -184,21 +184,21 @@ public class RequestRoleFragment extends DialogFragment { finish(); } - private void onRequestRoleStateChanged(int state) { + private void onAddRoleHolderStateChanged(int state) { AlertDialog dialog = (AlertDialog) getDialog(); switch (state) { - case RequestRoleLiveData.STATE_IDLE: + case AddRoleHolderStateLiveData.STATE_IDLE: dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(true); dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setEnabled(true); break; - case RequestRoleLiveData.STATE_ADDING: + case AddRoleHolderStateLiveData.STATE_ADDING: dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false); dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setEnabled(false); break; - case RequestRoleLiveData.STATE_SUCCESS: + case AddRoleHolderStateLiveData.STATE_SUCCESS: setResultOkAndFinish(); break; - case RequestRoleLiveData.STATE_FAILURE: + case AddRoleHolderStateLiveData.STATE_FAILURE: finish(); break; } diff --git a/src/com/android/packageinstaller/role/ui/RequestRoleViewModel.java b/src/com/android/packageinstaller/role/ui/RequestRoleViewModel.java index 6ebc7faaa..4a7a97dcb 100644 --- a/src/com/android/packageinstaller/role/ui/RequestRoleViewModel.java +++ b/src/com/android/packageinstaller/role/ui/RequestRoleViewModel.java @@ -25,10 +25,10 @@ import androidx.lifecycle.ViewModel; public class RequestRoleViewModel extends ViewModel { @NonNull - private RequestRoleLiveData mLiveData = new RequestRoleLiveData(); + private AddRoleHolderStateLiveData mLiveData = new AddRoleHolderStateLiveData(); @NonNull - public RequestRoleLiveData getLiveData() { + public AddRoleHolderStateLiveData getLiveData() { return mLiveData; } } -- GitLab From 71c79c197f3c49ddd5b36af0b2164b208d70e7d7 Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Fri, 7 Dec 2018 16:34:53 -0800 Subject: [PATCH 193/701] Hide default apps only when there are no qualifying apps. This change makes the default app UI hide a default app only when there are no qualifying apps, which is consistent with what we have in Settings app now. Bug: 110557011 Test: manual Change-Id: I28f10bf2e8c35adc0eb957f7d3980315ad8f0973 --- res/values/strings.xml | 7 +++++-- .../role/ui/DefaultAppFragment.java | 2 +- .../role/ui/DefaultAppListFragment.java | 20 +++++++++---------- .../role/ui/RoleListLiveData.java | 4 ++++ 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 1968cf6a0..c5fc14a16 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -405,8 +405,11 @@ No default apps - - No apps + + None + + + No apps diff --git a/src/com/android/packageinstaller/role/ui/DefaultAppFragment.java b/src/com/android/packageinstaller/role/ui/DefaultAppFragment.java index 5a49488a7..a3497bc19 100644 --- a/src/com/android/packageinstaller/role/ui/DefaultAppFragment.java +++ b/src/com/android/packageinstaller/role/ui/DefaultAppFragment.java @@ -98,7 +98,7 @@ public class DefaultAppFragment extends SettingsFragment @Override @StringRes protected int getEmptyTextResource() { - return R.string.no_apps_for_default_app; + return R.string.default_app_no_apps; } private void onRoleInfoChanged(@NonNull RoleInfo roleInfo) { diff --git a/src/com/android/packageinstaller/role/ui/DefaultAppListFragment.java b/src/com/android/packageinstaller/role/ui/DefaultAppListFragment.java index 4728f61f5..ef82dd2ea 100644 --- a/src/com/android/packageinstaller/role/ui/DefaultAppListFragment.java +++ b/src/com/android/packageinstaller/role/ui/DefaultAppListFragment.java @@ -100,12 +100,6 @@ public class DefaultAppListFragment extends SettingsFragment for (int roleItemsIndex = 0; roleItemsIndex < roleItemsSize; roleItemsIndex++) { RoleItem roleItem = roleItems.get(roleItemsIndex); - List holderApplicationInfos = roleItem.getHolderApplicationInfos(); - if (holderApplicationInfos.isEmpty()) { - // TODO: Handle Assistant which is visible even without holder. - continue; - } - Role role = roleItem.getRole(); Preference preference = oldPreferences.get(role.getName()); if (preference == null) { @@ -117,10 +111,16 @@ public class DefaultAppListFragment extends SettingsFragment preference.setOnPreferenceClickListener(this); } - ApplicationInfo holderApplicationInfo = holderApplicationInfos.get(0); - preference.setIcon(IconDrawableFactory.getBadgedIcon(context, holderApplicationInfo, - UserHandle.getUserHandleForUid(holderApplicationInfo.uid))); - preference.setSummary(Utils.getAppLabel(holderApplicationInfo, context)); + List holderApplicationInfos = roleItem.getHolderApplicationInfos(); + if (holderApplicationInfos.isEmpty()) { + preference.setIcon(null); + preference.setSummary(R.string.default_app_none); + } else { + ApplicationInfo holderApplicationInfo = holderApplicationInfos.get(0); + preference.setIcon(IconDrawableFactory.getBadgedIcon(context, holderApplicationInfo, + UserHandle.getUserHandleForUid(holderApplicationInfo.uid))); + preference.setSummary(Utils.getAppLabel(holderApplicationInfo, context)); + } // TODO: Ordering? preferenceScreen.addPreference(preference); diff --git a/src/com/android/packageinstaller/role/ui/RoleListLiveData.java b/src/com/android/packageinstaller/role/ui/RoleListLiveData.java index 78d33b2c7..f76fc9736 100644 --- a/src/com/android/packageinstaller/role/ui/RoleListLiveData.java +++ b/src/com/android/packageinstaller/role/ui/RoleListLiveData.java @@ -89,6 +89,10 @@ public class RoleListLiveData extends AsyncTaskLiveData> continue; } + if (role.getQualifyingPackages(mContext).isEmpty()) { + continue; + } + List holderApplicationInfos = new ArrayList<>(); List holderPackageNames = roleManager.getRoleHolders(role.getName()); int holderPackageNamesSize = holderPackageNames.size(); -- GitLab From 4ae320e418b1fe0ac635b5b5a8843590951e2f72 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Tue, 11 Dec 2018 13:16:29 -0800 Subject: [PATCH 194/701] Use the new app info header. Use the new app info header from SettingsLib that shows the app name and icon and has buttons to control it. For now I'm disabling those buttons, however, as I'm hoping to move the existing functionality into SettingsLib rather than copy-pasting it. Bug: 63532550 Test: Open screens, see new header. Change-Id: I412e62250931e88e7cfe3af74a6fad8677b63f81 --- Android.mk | 4 +- res/drawable/ic_delete.xml | 31 +++++ res/drawable/ic_force_stop.xml | 31 +++++ res/drawable/ic_open.xml | 25 +++++ res/layout/app_permission.xml | 2 +- res/layout/button_header.xml | 48 ++++++++ res/values/dimens.xml | 2 + res/values/strings.xml | 9 ++ .../ui/handheld/AppPermissionFragment.java | 8 +- .../handheld/AppPermissionUsageFragment.java | 4 +- .../ui/handheld/AppPermissionsFragment.java | 20 ++-- .../ui/handheld/SettingsWithButtonHeader.java | 106 ++++++++++++++++++ 12 files changed, 269 insertions(+), 21 deletions(-) create mode 100644 res/drawable/ic_delete.xml create mode 100644 res/drawable/ic_force_stop.xml create mode 100644 res/drawable/ic_open.xml create mode 100644 res/layout/button_header.xml create mode 100644 src/com/android/packageinstaller/permission/ui/handheld/SettingsWithButtonHeader.java diff --git a/Android.mk b/Android.mk index 64df055d3..48b0737aa 100644 --- a/Android.mk +++ b/Android.mk @@ -29,7 +29,9 @@ LOCAL_STATIC_ANDROID_LIBRARIES += \ SettingsLibRestrictedLockUtils \ SettingsLibAppPreference \ SettingsLibSearchWidget \ - SettingsLibSettingsSpinner + SettingsLibSettingsSpinner \ + SettingsLayoutPreference \ + ActionButtonsPreference LOCAL_STATIC_JAVA_LIBRARIES := \ androidx.annotation_annotation diff --git a/res/drawable/ic_delete.xml b/res/drawable/ic_delete.xml new file mode 100644 index 000000000..84e8982cf --- /dev/null +++ b/res/drawable/ic_delete.xml @@ -0,0 +1,31 @@ + + + + + + + \ No newline at end of file diff --git a/res/drawable/ic_force_stop.xml b/res/drawable/ic_force_stop.xml new file mode 100644 index 000000000..84e8982cf --- /dev/null +++ b/res/drawable/ic_force_stop.xml @@ -0,0 +1,31 @@ + + + + + + + \ No newline at end of file diff --git a/res/drawable/ic_open.xml b/res/drawable/ic_open.xml new file mode 100644 index 000000000..81ad64d61 --- /dev/null +++ b/res/drawable/ic_open.xml @@ -0,0 +1,25 @@ + + + + + \ No newline at end of file diff --git a/res/layout/app_permission.xml b/res/layout/app_permission.xml index 8c98948fc..1e65f23a9 100644 --- a/res/layout/app_permission.xml +++ b/res/layout/app_permission.xml @@ -21,7 +21,7 @@ android:layout_height="wrap_content" android:orientation="vertical"> - + + + + + + + + + + + + + + + + + diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 7b856fe59..cbeb646c7 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -53,4 +53,6 @@ 12dp 8dp + + 120dp diff --git a/res/values/strings.xml b/res/values/strings.xml index d84c07647..9474e1a15 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -407,6 +407,15 @@ No apps denied + + Open + + + Uninstall + + + Force stop + Default apps diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java index 43fe2c68d..dabbfdb3c 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java @@ -72,7 +72,7 @@ import java.util.List; * *

Allows the user to control whether the app is granted the permission. */ -public class AppPermissionFragment extends PermissionsFrameFragment { +public class AppPermissionFragment extends SettingsWithButtonHeader { private static final String LOG_TAG = "AppPermissionFragment"; @Retention(SOURCE) @@ -178,10 +178,8 @@ public class AppPermissionFragment extends PermissionsFrameFragment { } String appLabel = Utils.getAppLabel(mGroup.getApp().applicationInfo, context); - - ((ImageView) root.requireViewById(R.id.icon)).setImageDrawable(getAppIcon()); - ((TextView) root.requireViewById(R.id.name)).setText(appLabel); - root.requireViewById(R.id.info).setVisibility(View.GONE); + setHeader(getAppIcon(), appLabel); + updateHeader(root.requireViewById(R.id.button_header)); ((TextView) root.requireViewById(R.id.permission_message)).setText( context.getString(R.string.app_permission_header, mGroup.getLabel(), appLabel)); diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java index 0e0b3e9d9..7c2a91578 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java @@ -59,7 +59,7 @@ import java.util.Set; *

Shows a list of app usage of permission groups, each of which links to * AppPermissionsFragment. */ -public class AppPermissionUsageFragment extends SettingsWithHeader { +public class AppPermissionUsageFragment extends SettingsWithButtonHeader { private static final String LOG_TAG = "AppPermissionUsageFragment"; @@ -119,7 +119,7 @@ public class AppPermissionUsageFragment extends SettingsWithHeader { Drawable icon = IconDrawableFactory.getBadgedIcon(getActivity(), appInfo, UserHandle.getUserHandleForUid(appInfo.uid)); CharSequence label = appInfo.loadLabel(getActivity().getPackageManager()); - setHeader(icon, label, null); + setHeader(icon, label); } } diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java index dcb4132bc..a9063936a 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java @@ -24,10 +24,8 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.graphics.drawable.Drawable; -import android.net.Uri; import android.os.Bundle; import android.os.UserHandle; -import android.provider.Settings; import android.util.Log; import android.view.Menu; import android.view.MenuInflater; @@ -55,7 +53,7 @@ import java.util.ArrayList; * *

Shows the list of permission groups the app has requested at one permission for. */ -public final class AppPermissionsFragment extends SettingsWithHeader { +public final class AppPermissionsFragment extends SettingsWithButtonHeader { private static final String LOG_TAG = "ManagePermsFragment"; @@ -160,20 +158,15 @@ public final class AppPermissionsFragment extends SettingsWithHeader { .commit(); } - private static void bindUi(SettingsWithHeader fragment, PackageInfo packageInfo) { + private static void bindUi(SettingsWithButtonHeader fragment, PackageInfo packageInfo) { Activity activity = fragment.getActivity(); PackageManager pm = activity.getPackageManager(); ApplicationInfo appInfo = packageInfo.applicationInfo; - Intent infoIntent = null; - if (!activity.getIntent().getBooleanExtra(EXTRA_HIDE_INFO_BUTTON, false)) { - infoIntent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) - .setData(Uri.fromParts("package", packageInfo.packageName, null)); - } Drawable icon = IconDrawableFactory.getBadgedIcon(activity, appInfo, UserHandle.getUserHandleForUid(appInfo.uid)); CharSequence label = appInfo.loadLabel(pm); - fragment.setHeader(icon, label, infoIntent); + fragment.setHeader(icon, label); ActionBar ab = activity.getActionBar(); if (ab != null) { @@ -291,14 +284,17 @@ public final class AppPermissionsFragment extends SettingsWithHeader { } } - public static class AdditionalPermissionsFragment extends SettingsWithHeader { + /** + * Class that shows additional permissions. + */ + public static class AdditionalPermissionsFragment extends SettingsWithButtonHeader { AppPermissionsFragment mOuterFragment; @Override public void onCreate(Bundle savedInstanceState) { mOuterFragment = (AppPermissionsFragment) getTargetFragment(); super.onCreate(savedInstanceState); - setHeader(mOuterFragment.mIcon, mOuterFragment.mLabel, mOuterFragment.mInfoIntent); + setHeader(mOuterFragment.mIcon, mOuterFragment.mLabel); setHasOptionsMenu(true); setPreferenceScreen(mOuterFragment.mExtraScreen); } diff --git a/src/com/android/packageinstaller/permission/ui/handheld/SettingsWithButtonHeader.java b/src/com/android/packageinstaller/permission/ui/handheld/SettingsWithButtonHeader.java new file mode 100644 index 000000000..719596b97 --- /dev/null +++ b/src/com/android/packageinstaller/permission/ui/handheld/SettingsWithButtonHeader.java @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2015 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.packageinstaller.permission.ui.handheld; + +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.DrawableRes; +import androidx.annotation.NonNull; + +import com.android.packageinstaller.DeviceUtils; +import com.android.permissioncontroller.R; + +/** + * A class that contains a header with a row of buttons. + */ +public abstract class SettingsWithButtonHeader extends PermissionsFrameFragment { + + private View mHeader; + protected Drawable mIcon; + protected CharSequence mLabel; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + ViewGroup root = (ViewGroup) super.onCreateView(inflater, container, savedInstanceState); + + if (!DeviceUtils.isTelevision(getContext())) { + mHeader = inflater.inflate(R.layout.button_header, root, false); + getPreferencesContainer().addView(mHeader, 0); + + updateHeader(mHeader); + } + + return root; + } + + /** + * Set the icon and label to use in the header. + * + * @param icon the icon + * @param label the label + */ + public void setHeader(@NonNull Drawable icon, @NonNull CharSequence label) { + mIcon = icon; + mLabel = label; + updateHeader(mHeader); + } + + /** + * Updates the header to use the correct icon, title, and buttons. + * + * @param header the View that contains the components. + */ + protected void updateHeader(@NonNull View header) { + if (header != null) { + ImageView appIcon = header.requireViewById(R.id.entity_header_icon); + appIcon.setImageDrawable(mIcon); + + TextView appName = header.requireViewById(R.id.entity_header_title); + appName.setText(mLabel); + + Button button1 = header.requireViewById(R.id.button1); + button1.setText(R.string.launch_app); + setButtonIcon(button1, R.drawable.ic_open); + button1.setEnabled(false); + + Button button2 = header.requireViewById(R.id.button2); + button2.setText(R.string.uninstall_app); + setButtonIcon(button2, R.drawable.ic_delete); + button2.setEnabled(false); + + Button button3 = header.requireViewById(R.id.button3); + button3.setText(R.string.force_stop_app); + setButtonIcon(button3, R.drawable.ic_force_stop); + button3.setEnabled(false); + + header.requireViewById(R.id.button4).setVisibility(View.GONE); + } + } + + private void setButtonIcon(@NonNull Button button, @DrawableRes int iconResId) { + button.setCompoundDrawablesWithIntrinsicBounds(null, getContext().getDrawable(iconResId), + null, null); + } +} -- GitLab From bf08ec3ddfb1e5b4f0cadda98c061038ed0bfd79 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Wed, 12 Dec 2018 10:26:55 -0800 Subject: [PATCH 195/701] Do not use truncated app label when there is room. Change-Id: I3e2de3e446fe0ae7c2c7bd7b5df8d8a56354b105 Fixes: 120872584 Test: See app label without truncation. --- .../ui/handheld/AppPermissionFragment.java | 2 +- .../ui/handheld/PermissionAppsFragment.java | 4 +-- .../permission/utils/Utils.java | 33 +++++++++++++++++-- 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java index dabbfdb3c..165aac6b4 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java @@ -177,7 +177,7 @@ public class AppPermissionFragment extends SettingsWithButtonHeader { return root; } - String appLabel = Utils.getAppLabel(mGroup.getApp().applicationInfo, context); + String appLabel = Utils.getFullAppLabel(mGroup.getApp().applicationInfo, context); setHeader(getAppIcon(), appLabel); updateHeader(root.requireViewById(R.id.button_header)); diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java index 1f8ea2811..93b84fb49 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java @@ -20,7 +20,6 @@ import android.content.Context; import android.content.Intent; import android.graphics.drawable.Drawable; import android.os.Bundle; -import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; import android.view.Menu; @@ -269,8 +268,7 @@ public final class PermissionAppsFragment extends PermissionsFrameFragment imple PermissionControlPreference pref = new PermissionControlPreference(context, group); pref.setKey(key); pref.setIcon(app.getIcon()); - pref.setTitle(app.getAppInfo().loadSafeLabel(context.getPackageManager(), 0, - TextUtils.SAFE_STRING_FLAG_TRIM | TextUtils.SAFE_STRING_FLAG_FIRST_LINE)); + pref.setTitle(Utils.getFullAppLabel(app.getAppInfo(), context)); pref.setEllipsizeEnd(); pref.useSmallerIcon(); pref.setGroupSummary(group); diff --git a/src/com/android/packageinstaller/permission/utils/Utils.java b/src/com/android/packageinstaller/permission/utils/Utils.java index be6870c4c..ffdb5be0c 100644 --- a/src/com/android/packageinstaller/permission/utils/Utils.java +++ b/src/com/android/packageinstaller/permission/utils/Utils.java @@ -330,7 +330,7 @@ public final class Utils { } /** - * Get the label for an application. + * Get the label for an application, truncating if it is too long. * * @param applicationInfo the {@link ApplicationInfo} of the application * @param context the {@code Context} to retrieve {@code PackageManager} @@ -340,8 +340,37 @@ public final class Utils { @NonNull public static String getAppLabel(@NonNull ApplicationInfo applicationInfo, @NonNull Context context) { + return getAppLabel(applicationInfo, DEFAULT_MAX_LABEL_SIZE_PX, context); + } + + /** + * Get the full label for an application without truncation. + * + * @param applicationInfo the {@link ApplicationInfo} of the application + * @param context the {@code Context} to retrieve {@code PackageManager} + * + * @return the label for the application + */ + @NonNull + public static String getFullAppLabel(@NonNull ApplicationInfo applicationInfo, + @NonNull Context context) { + return getAppLabel(applicationInfo, 0, context); + } + + /** + * Get the label for an application with the ability to control truncating. + * + * @param applicationInfo the {@link ApplicationInfo} of the application + * @param ellipsizeDip see {@link TextUtils#makeSafeForPresentation}. + * @param context the {@code Context} to retrieve {@code PackageManager} + * + * @return the label for the application + */ + @NonNull + private static String getAppLabel(@NonNull ApplicationInfo applicationInfo, float ellipsizeDip, + @NonNull Context context) { return BidiFormatter.getInstance().unicodeWrap(applicationInfo.loadSafeLabel( - context.getPackageManager(), DEFAULT_MAX_LABEL_SIZE_PX, + context.getPackageManager(), ellipsizeDip, TextUtils.SAFE_STRING_FLAG_TRIM | TextUtils.SAFE_STRING_FLAG_FIRST_LINE) .toString()); } -- GitLab From 86e0e67967de5dba9fefe6ce5755ccc984d2e156 Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Wed, 12 Dec 2018 14:28:23 -0800 Subject: [PATCH 196/701] Update permission controller version ... now that the new UI and role management is code complete. Test: Check version in settings Change-Id: I0e5e45bbed535f7ca902e90e4b8f5baae8201aea --- AndroidManifest.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index bc1eae2c3..5fe0d78d7 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1,8 +1,8 @@ + package="com.android.permissioncontroller" coreApp="true" android:versionCode="290100" + android:versionName="29.1.0"> -- GitLab From 9ce4a3ce1cbe18ed4ec82d4f0a076c89343a598b Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Wed, 12 Dec 2018 15:55:48 -0800 Subject: [PATCH 197/701] Add work profile support for the new Default apps UI. This change adds work profile support for the new Default apps UI, similar to what we have now in Settings app. Bug: 110557011 Test: manual Change-Id: I6a0b665f7f86644023b6b13347ff81a94d34807e --- res/values/strings.xml | 3 + .../role/model/PreferredActivity.java | 4 +- .../role/model/RequiredActivity.java | 7 +- .../role/model/RequiredBroadcastReceiver.java | 7 +- .../role/model/RequiredComponent.java | 27 ++++--- .../role/model/RequiredContentProvider.java | 7 +- .../role/model/RequiredService.java | 7 +- .../packageinstaller/role/model/Role.java | 11 ++- .../role/ui/AddRoleHolderStateLiveData.java | 7 +- .../role/ui/DefaultAppActivity.java | 15 +++- .../role/ui/DefaultAppFragment.java | 19 +++-- .../role/ui/DefaultAppListFragment.java | 80 +++++++++++++++---- .../role/ui/DefaultAppViewModel.java | 15 +++- .../role/ui/RequestRoleFragment.java | 4 +- .../role/ui/RoleListLiveData.java | 27 ++++--- .../role/ui/RoleListViewModel.java | 69 +++++++++++++++- .../role/ui/RoleLiveData.java | 23 +++--- .../role/utils/PackageUtils.java | 23 ++++++ 18 files changed, 269 insertions(+), 86 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 9474e1a15..fcf8b3b0a 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -426,6 +426,9 @@ No default apps + + Default for work + None diff --git a/src/com/android/packageinstaller/role/model/PreferredActivity.java b/src/com/android/packageinstaller/role/model/PreferredActivity.java index ad96e45b2..75553d5b4 100644 --- a/src/com/android/packageinstaller/role/model/PreferredActivity.java +++ b/src/com/android/packageinstaller/role/model/PreferredActivity.java @@ -20,6 +20,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.IntentFilter; import android.content.pm.PackageManager; +import android.os.Process; import androidx.annotation.NonNull; @@ -68,7 +69,8 @@ public class PreferredActivity { */ public void configure(@NonNull String packageName, @NonNull Context context) { IntentFilter intentFilter = mActivity.getIntentFilterData().createIntentFilter(); - List activities = mActivity.getQualifyingComponents(context); + List activities = mActivity.getQualifyingComponentsAsUser( + Process.myUserHandle(), context); ComponentName packageActivity = mActivity.getQualifyingComponentForPackage( packageName, context); // TODO: STOPSHIP: Race condition, what if packageActivity became null? Just don't crash? diff --git a/src/com/android/packageinstaller/role/model/RequiredActivity.java b/src/com/android/packageinstaller/role/model/RequiredActivity.java index b39bbd1d5..742e7be97 100644 --- a/src/com/android/packageinstaller/role/model/RequiredActivity.java +++ b/src/com/android/packageinstaller/role/model/RequiredActivity.java @@ -22,6 +22,7 @@ import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.Bundle; +import android.os.UserHandle; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -40,10 +41,10 @@ public class RequiredActivity extends RequiredComponent { @NonNull @Override - protected List queryIntentComponents(@NonNull Intent intent, int flags, - @NonNull Context context) { + protected List queryIntentComponentsAsUser(@NonNull Intent intent, int flags, + @NonNull UserHandle user, @NonNull Context context) { PackageManager packageManager = context.getPackageManager(); - return packageManager.queryIntentActivities(intent, flags); + return packageManager.queryIntentActivitiesAsUser(intent, flags, user); } @NonNull diff --git a/src/com/android/packageinstaller/role/model/RequiredBroadcastReceiver.java b/src/com/android/packageinstaller/role/model/RequiredBroadcastReceiver.java index 21eb670af..37a8f1ca1 100644 --- a/src/com/android/packageinstaller/role/model/RequiredBroadcastReceiver.java +++ b/src/com/android/packageinstaller/role/model/RequiredBroadcastReceiver.java @@ -22,6 +22,7 @@ import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.Bundle; +import android.os.UserHandle; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -40,10 +41,10 @@ public class RequiredBroadcastReceiver extends RequiredComponent { @NonNull @Override - protected List queryIntentComponents(@NonNull Intent intent, int flags, - @NonNull Context context) { + protected List queryIntentComponentsAsUser(@NonNull Intent intent, int flags, + @NonNull UserHandle user, @NonNull Context context) { PackageManager packageManager = context.getPackageManager(); - return packageManager.queryBroadcastReceivers(intent, flags); + return packageManager.queryBroadcastReceiversAsUser(intent, flags, user); } @NonNull diff --git a/src/com/android/packageinstaller/role/model/RequiredComponent.java b/src/com/android/packageinstaller/role/model/RequiredComponent.java index e810af696..951d2a02c 100644 --- a/src/com/android/packageinstaller/role/model/RequiredComponent.java +++ b/src/com/android/packageinstaller/role/model/RequiredComponent.java @@ -22,6 +22,8 @@ import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.Bundle; +import android.os.Process; +import android.os.UserHandle; import android.util.ArraySet; import android.util.Log; @@ -96,8 +98,8 @@ public abstract class RequiredComponent { @Nullable public ComponentName getQualifyingComponentForPackage(@NonNull String packageName, @NonNull Context context) { - List componentNames = getQualifyingComponents(packageName, - context); + List componentNames = getQualifyingComponentsInternal(packageName, + Process.myUserHandle(), context); return !componentNames.isEmpty() ? componentNames.get(0) : null; } @@ -105,20 +107,22 @@ public abstract class RequiredComponent { * Get the list of components that match this required component, at most one component per * package and ordered from best to worst. * + * @param user the user to get the qualifying components. * @param context the {@code Context} to retrieve system services * * @return the list of matching components * - * @see Role#getQualifyingPackages(Context) + * @see Role#getQualifyingPackagesAsUser(UserHandle, Context) */ @NonNull - public List getQualifyingComponents(@NonNull Context context) { - return getQualifyingComponents(null, context); + public List getQualifyingComponentsAsUser(@NonNull UserHandle user, + @NonNull Context context) { + return getQualifyingComponentsInternal(null, user, context); } @NonNull - private List getQualifyingComponents(@Nullable String packageName, - @NonNull Context context) { + private List getQualifyingComponentsInternal(@Nullable String packageName, + @NonNull UserHandle user, @NonNull Context context) { Intent intent = mIntentFilterData.createIntent(); if (packageName != null) { intent.setPackage(packageName); @@ -129,7 +133,7 @@ public abstract class RequiredComponent { if (hasMetaData) { flags |= PackageManager.GET_META_DATA; } - List resolveInfos = queryIntentComponents(intent, flags, context); + List resolveInfos = queryIntentComponentsAsUser(intent, flags, user, context); ArraySet componentPackageNames = new ArraySet<>(); List componentNames = new ArrayList<>(); @@ -182,14 +186,15 @@ public abstract class RequiredComponent { * to worst. * * @param intent the {@code Intent} to match against - * @param flags the flags to be used for this query + * @param flags the flags for this query + * @param user the user for this query * @param context the {@code Context} to retrieve system services * * @return the list of matching components */ @NonNull - protected abstract List queryIntentComponents(@NonNull Intent intent, int flags, - @NonNull Context context); + protected abstract List queryIntentComponentsAsUser(@NonNull Intent intent, + int flags, @NonNull UserHandle user, @NonNull Context context); /** * Get the {@code ComponentName} of a component. diff --git a/src/com/android/packageinstaller/role/model/RequiredContentProvider.java b/src/com/android/packageinstaller/role/model/RequiredContentProvider.java index eb0f5f079..776c83997 100644 --- a/src/com/android/packageinstaller/role/model/RequiredContentProvider.java +++ b/src/com/android/packageinstaller/role/model/RequiredContentProvider.java @@ -22,6 +22,7 @@ import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.Bundle; +import android.os.UserHandle; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -40,10 +41,10 @@ public class RequiredContentProvider extends RequiredComponent { @NonNull @Override - protected List queryIntentComponents(@NonNull Intent intent, int flags, - @NonNull Context context) { + protected List queryIntentComponentsAsUser(@NonNull Intent intent, int flags, + @NonNull UserHandle user, @NonNull Context context) { PackageManager packageManager = context.getPackageManager(); - return packageManager.queryIntentContentProviders(intent, flags); + return packageManager.queryIntentContentProvidersAsUser(intent, flags, user); } @NonNull diff --git a/src/com/android/packageinstaller/role/model/RequiredService.java b/src/com/android/packageinstaller/role/model/RequiredService.java index 9bab7b9f7..17fc5f079 100644 --- a/src/com/android/packageinstaller/role/model/RequiredService.java +++ b/src/com/android/packageinstaller/role/model/RequiredService.java @@ -22,6 +22,7 @@ import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.Bundle; +import android.os.UserHandle; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -40,10 +41,10 @@ public class RequiredService extends RequiredComponent { @NonNull @Override - protected List queryIntentComponents(@NonNull Intent intent, int flags, - @NonNull Context context) { + protected List queryIntentComponentsAsUser(@NonNull Intent intent, int flags, + @NonNull UserHandle user, @NonNull Context context) { PackageManager packageManager = context.getPackageManager(); - return packageManager.queryIntentServices(intent, flags); + return packageManager.queryIntentServicesAsUser(intent, flags, user); } @NonNull diff --git a/src/com/android/packageinstaller/role/model/Role.java b/src/com/android/packageinstaller/role/model/Role.java index 9527d0eed..200499d8d 100644 --- a/src/com/android/packageinstaller/role/model/Role.java +++ b/src/com/android/packageinstaller/role/model/Role.java @@ -20,6 +20,7 @@ import android.app.ActivityManager; import android.content.ComponentName; import android.content.Context; import android.content.pm.ApplicationInfo; +import android.os.UserHandle; import android.util.ArrayMap; import android.util.Log; @@ -160,15 +161,17 @@ public class Role { } /** - * Get the set of packages that are qualified for this role, i.e. packages containing all the + * Get the list of packages that are qualified for this role, i.e. packages containing all the * required components. * + * @param user the user to get the qualifying packages. * @param context the {@code Context} to retrieve system services * * @return the set of packages that are qualified for this role */ @NonNull - public List getQualifyingPackages(@NonNull Context context) { + public List getQualifyingPackagesAsUser(@NonNull UserHandle user, + @NonNull Context context) { ArrayMap packageComponentCountMap = new ArrayMap<>(); int requiredComponentsSize = mRequiredComponents.size(); for (int requiredComponentsIndex = 0; requiredComponentsIndex < requiredComponentsSize; @@ -176,8 +179,8 @@ public class Role { RequiredComponent requiredComponent = mRequiredComponents.get(requiredComponentsIndex); // This returns at most one component per package. - List qualifyingComponents = requiredComponent.getQualifyingComponents( - context); + List qualifyingComponents = + requiredComponent.getQualifyingComponentsAsUser(user, context); int qualifyingComponentsSize = qualifyingComponents.size(); for (int qualifyingComponentsIndex = 0; qualifyingComponentsIndex < qualifyingComponentsSize; diff --git a/src/com/android/packageinstaller/role/ui/AddRoleHolderStateLiveData.java b/src/com/android/packageinstaller/role/ui/AddRoleHolderStateLiveData.java index 45c0e8061..9606c6db4 100644 --- a/src/com/android/packageinstaller/role/ui/AddRoleHolderStateLiveData.java +++ b/src/com/android/packageinstaller/role/ui/AddRoleHolderStateLiveData.java @@ -19,7 +19,6 @@ package com.android.packageinstaller.role.ui; import android.app.role.RoleManager; import android.app.role.RoleManagerCallback; import android.content.Context; -import android.os.Process; import android.os.UserHandle; import android.util.Log; @@ -50,10 +49,11 @@ public class AddRoleHolderStateLiveData extends LiveData { * * @param roleName the name of the role * @param packageName the package name of the application + * @param user the user to add the role holder for * @param context the {@code Context} to retrieve system services */ - public void addRoleHolder(@NonNull String roleName, @NonNull String packageName, - @NonNull Context context) { + public void addRoleHolderAsUser(@NonNull String roleName, @NonNull String packageName, + @NonNull UserHandle user, @NonNull Context context) { if (getValue() != STATE_IDLE) { Log.e(LOG_TAG, "Already (tried) adding package as role holder, requested role: " + roleName + ", requested package: " + packageName); @@ -64,7 +64,6 @@ public class AddRoleHolderStateLiveData extends LiveData { setValue(STATE_ADDING); RoleManager roleManager = context.getSystemService(RoleManager.class); - UserHandle user = Process.myUserHandle(); Executor executor = context.getMainExecutor(); roleManager.addRoleHolderAsUser(roleName, packageName, user, executor, new RoleManagerCallback() { diff --git a/src/com/android/packageinstaller/role/ui/DefaultAppActivity.java b/src/com/android/packageinstaller/role/ui/DefaultAppActivity.java index b1ae2c0a2..67b2dc9b8 100644 --- a/src/com/android/packageinstaller/role/ui/DefaultAppActivity.java +++ b/src/com/android/packageinstaller/role/ui/DefaultAppActivity.java @@ -19,6 +19,7 @@ package com.android.packageinstaller.role.ui; import android.content.Context; import android.content.Intent; import android.os.Bundle; +import android.os.UserHandle; import android.util.Log; import androidx.annotation.NonNull; @@ -39,21 +40,27 @@ public class DefaultAppActivity extends FragmentActivity { * Create an intent for starting this activity. * * @param roleName the name of the role for the default app + * @param user the user for the default app * @param context the context to create the intent * * @return an intent to start this activity */ @NonNull - public static Intent createIntent(@NonNull String roleName, @NonNull Context context) { + public static Intent createIntent(@NonNull String roleName, @NonNull UserHandle user, + @NonNull Context context) { return new Intent(context, DefaultAppActivity.class) - .putExtra(DefaultAppFragment.EXTRA_ROLE_NAME, roleName); + .putExtra(DefaultAppFragment.EXTRA_ROLE_NAME, roleName) + .putExtra(Intent.EXTRA_USER, user); } @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - String roleName = getIntent().getStringExtra(DefaultAppFragment.EXTRA_ROLE_NAME); + Intent intent = getIntent(); + String roleName = intent.getStringExtra(DefaultAppFragment.EXTRA_ROLE_NAME); + UserHandle user = intent.getParcelableExtra(Intent.EXTRA_USER); + Role role = Roles.getRoles(this).get(roleName); if (role == null) { Log.e(LOG_TAG, "Unknown role: " + roleName); @@ -62,7 +69,7 @@ public class DefaultAppActivity extends FragmentActivity { } if (savedInstanceState == null) { - DefaultAppFragment fragment = DefaultAppFragment.newInstance(roleName); + DefaultAppFragment fragment = DefaultAppFragment.newInstance(roleName, user); getSupportFragmentManager().beginTransaction() .add(android.R.id.content, fragment) .commit(); diff --git a/src/com/android/packageinstaller/role/ui/DefaultAppFragment.java b/src/com/android/packageinstaller/role/ui/DefaultAppFragment.java index a3497bc19..efa588787 100644 --- a/src/com/android/packageinstaller/role/ui/DefaultAppFragment.java +++ b/src/com/android/packageinstaller/role/ui/DefaultAppFragment.java @@ -18,6 +18,7 @@ package com.android.packageinstaller.role.ui; import android.app.Activity; import android.content.Context; +import android.content.Intent; import android.content.pm.ApplicationInfo; import android.os.Bundle; import android.os.UserHandle; @@ -54,6 +55,8 @@ public class DefaultAppFragment extends SettingsFragment private String mRoleName; + private UserHandle mUser; + private Role mRole; private DefaultAppViewModel mViewModel; @@ -61,15 +64,18 @@ public class DefaultAppFragment extends SettingsFragment /** * Create a new instance of this fragment. * - * @param roleName the name of the role to be managed + * @param roleName the name of the role for the default app + * @param user the user for the default app * * @return a new instance of this fragment */ @NonNull - public static DefaultAppFragment newInstance(@NonNull String roleName) { + public static DefaultAppFragment newInstance(@NonNull String roleName, + @NonNull UserHandle user) { DefaultAppFragment fragment = new DefaultAppFragment(); Bundle arguments = new Bundle(); arguments.putString(EXTRA_ROLE_NAME, roleName); + arguments.putParcelable(Intent.EXTRA_USER, user); fragment.setArguments(arguments); return fragment; } @@ -78,7 +84,9 @@ public class DefaultAppFragment extends SettingsFragment public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - mRoleName = getArguments().getString(EXTRA_ROLE_NAME); + Bundle arguments = getArguments(); + mRoleName = arguments.getString(EXTRA_ROLE_NAME); + mUser = arguments.getParcelable(Intent.EXTRA_USER); } @Override @@ -89,7 +97,7 @@ public class DefaultAppFragment extends SettingsFragment mRole = Roles.getRoles(activity).get(mRoleName); activity.setTitle(mRole.getLabelResource()); - mViewModel = ViewModelProviders.of(this, new DefaultAppViewModel.Factory(mRole, + mViewModel = ViewModelProviders.of(this, new DefaultAppViewModel.Factory(mRole, mUser, activity.getApplication())).get(DefaultAppViewModel.class); mViewModel.getRoleLiveData().observe(this, this::onRoleInfoChanged); mViewModel.getAddRoleHolderStateLiveData().observe(this, this::onAddRoleHolderStateChanged); @@ -173,7 +181,8 @@ public class DefaultAppFragment extends SettingsFragment } String packageName = preference.getKey(); - addRoleHolderStateLiveData.addRoleHolder(mRoleName, packageName, requireContext()); + addRoleHolderStateLiveData.addRoleHolderAsUser(mRoleName, packageName, mUser, + requireContext()); return true; } } diff --git a/src/com/android/packageinstaller/role/ui/DefaultAppListFragment.java b/src/com/android/packageinstaller/role/ui/DefaultAppListFragment.java index ef82dd2ea..64a726737 100644 --- a/src/com/android/packageinstaller/role/ui/DefaultAppListFragment.java +++ b/src/com/android/packageinstaller/role/ui/DefaultAppListFragment.java @@ -28,6 +28,8 @@ import androidx.annotation.Nullable; import androidx.annotation.StringRes; import androidx.lifecycle.ViewModelProviders; import androidx.preference.Preference; +import androidx.preference.PreferenceCategory; +import androidx.preference.PreferenceGroup; import androidx.preference.PreferenceManager; import androidx.preference.PreferenceScreen; @@ -46,6 +48,8 @@ public class DefaultAppListFragment extends SettingsFragment private static final String LOG_TAG = DefaultAppListFragment.class.getSimpleName(); + private static final String PREFERENCE_KEY_WORK_CATEGORY = "work_category"; + private RoleListViewModel mViewModel; /** @@ -64,7 +68,10 @@ public class DefaultAppListFragment extends SettingsFragment mViewModel = ViewModelProviders.of(this, new RoleListViewModel.Factory(true, requireActivity().getApplication())).get(RoleListViewModel.class); - mViewModel.getLiveData().observe(this, this::onRoleListChanged); + mViewModel.getLiveData().observe(this, roleItems -> onRoleListChanged()); + if (mViewModel.hasWorkProfile()) { + mViewModel.getWorkLiveData().observe(this, roleItems -> onRoleListChanged()); + } } @Override @@ -78,27 +85,72 @@ public class DefaultAppListFragment extends SettingsFragment return R.string.help_uri_default_apps; } - private void onRoleListChanged(@NonNull List roleItems) { + private void onRoleListChanged() { + List roleItems = mViewModel.getLiveData().getValue(); + if (roleItems == null) { + return; + } + boolean hasWorkProfile = mViewModel.hasWorkProfile(); + List workRoleItems = null; + if (hasWorkProfile) { + workRoleItems = mViewModel.getWorkLiveData().getValue(); + if (workRoleItems == null) { + return; + } + } + PreferenceManager preferenceManager = getPreferenceManager(); Context context = preferenceManager.getContext(); - PreferenceScreen preferenceScreen = getPreferenceScreen(); ArrayMap oldPreferences = new ArrayMap<>(); + PreferenceCategory oldWorkPreferenceCategory = null; + ArrayMap oldWorkPreferences = new ArrayMap<>(); if (preferenceScreen == null) { preferenceScreen = preferenceManager.createPreferenceScreen(context); setPreferenceScreen(preferenceScreen); } else { - for (int i = preferenceScreen.getPreferenceCount() - 1; i >= 0; --i) { - Preference preference = preferenceScreen.getPreference(i); + oldWorkPreferenceCategory = (PreferenceCategory) preferenceScreen.findPreference( + PREFERENCE_KEY_WORK_CATEGORY); + if (oldWorkPreferenceCategory != null) { + clearPreferences(oldWorkPreferenceCategory, oldWorkPreferences); + preferenceScreen.removePreference(oldWorkPreferenceCategory); + } + clearPreferences(preferenceScreen, oldPreferences); + } - preferenceScreen.removePreference(preference); - oldPreferences.put(preference.getKey(), preference); + addPreferences(preferenceScreen, roleItems, oldPreferences, this, mViewModel.getUser(), + context); + if (hasWorkProfile) { + PreferenceCategory workPreferenceCategory = oldWorkPreferenceCategory; + if (workPreferenceCategory == null) { + workPreferenceCategory = new PreferenceCategory(context); + workPreferenceCategory.setKey(PREFERENCE_KEY_WORK_CATEGORY); + workPreferenceCategory.setTitle(R.string.default_apps_for_work); } + preferenceScreen.addPreference(workPreferenceCategory); + addPreferences(workPreferenceCategory, workRoleItems, oldWorkPreferences, this, + mViewModel.getWorkProfile(), context); } + updateState(); + } + + private static void clearPreferences(@NonNull PreferenceGroup preferenceGroup, + @NonNull ArrayMap oldPreferences) { + for (int i = preferenceGroup.getPreferenceCount() - 1; i >= 0; --i) { + Preference Preference = preferenceGroup.getPreference(i); + + oldPreferences.put(Preference.getKey(), Preference); + } + } + + private static void addPreferences(@NonNull PreferenceGroup preferenceGroup, + @NonNull List roleItems, @NonNull ArrayMap oldPreferences, + @NonNull Preference.OnPreferenceClickListener listener, @NonNull UserHandle user, + @NonNull Context context) { int roleItemsSize = roleItems.size(); - for (int roleItemsIndex = 0; roleItemsIndex < roleItemsSize; roleItemsIndex++) { - RoleItem roleItem = roleItems.get(roleItemsIndex); + for (int i = 0; i < roleItemsSize; i++) { + RoleItem roleItem = roleItems.get(i); Role role = roleItem.getRole(); Preference preference = oldPreferences.get(role.getName()); @@ -108,7 +160,8 @@ public class DefaultAppListFragment extends SettingsFragment preference.setIconSpaceReserved(true); preference.setTitle(role.getLabelResource()); preference.setPersistent(false); - preference.setOnPreferenceClickListener(this); + preference.setOnPreferenceClickListener(listener); + preference.getExtras().putParcelable(Intent.EXTRA_USER, user); } List holderApplicationInfos = roleItem.getHolderApplicationInfos(); @@ -123,16 +176,15 @@ public class DefaultAppListFragment extends SettingsFragment } // TODO: Ordering? - preferenceScreen.addPreference(preference); + preferenceGroup.addPreference(preference); } - - updateState(); } @Override public boolean onPreferenceClick(@NonNull Preference preference) { String roleName = preference.getKey(); - Intent intent = DefaultAppActivity.createIntent(roleName, requireContext()); + UserHandle user = preference.getExtras().getParcelable(Intent.EXTRA_USER); + Intent intent = DefaultAppActivity.createIntent(roleName, user, requireContext()); startActivity(intent); return true; } diff --git a/src/com/android/packageinstaller/role/ui/DefaultAppViewModel.java b/src/com/android/packageinstaller/role/ui/DefaultAppViewModel.java index 163327aa7..b51191a82 100644 --- a/src/com/android/packageinstaller/role/ui/DefaultAppViewModel.java +++ b/src/com/android/packageinstaller/role/ui/DefaultAppViewModel.java @@ -17,6 +17,7 @@ package com.android.packageinstaller.role.ui; import android.app.Application; +import android.os.UserHandle; import androidx.annotation.NonNull; import androidx.lifecycle.AndroidViewModel; @@ -37,10 +38,11 @@ public class DefaultAppViewModel extends AndroidViewModel { private final AddRoleHolderStateLiveData mAddRoleHolderStateLiveData = new AddRoleHolderStateLiveData(); - public DefaultAppViewModel(@NonNull Role role, @NonNull Application application) { + public DefaultAppViewModel(@NonNull Role role, @NonNull UserHandle user, + @NonNull Application application) { super(application); - mRoleLiveData = new RoleLiveData(role, application); + mRoleLiveData = new RoleLiveData(role, user, application); } @NonNull @@ -61,11 +63,16 @@ public class DefaultAppViewModel extends AndroidViewModel { @NonNull private Role mRole; + @NonNull + private UserHandle mUser; + @NonNull private Application mApplication; - public Factory(@NonNull Role role, @NonNull Application application) { + public Factory(@NonNull Role role, @NonNull UserHandle user, + @NonNull Application application) { mRole = role; + mUser = user; mApplication = application; } @@ -73,7 +80,7 @@ public class DefaultAppViewModel extends AndroidViewModel { @Override public T create(@NonNull Class modelClass) { //noinspection unchecked - return (T) new DefaultAppViewModel(mRole, mApplication); + return (T) new DefaultAppViewModel(mRole, mUser, mApplication); } } } diff --git a/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java b/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java index c9ed25090..fd185e6cf 100644 --- a/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java +++ b/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java @@ -25,6 +25,7 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.os.Bundle; +import android.os.Process; import android.text.Html; import android.util.Log; @@ -205,7 +206,8 @@ public class RequestRoleFragment extends DialogFragment { } private void addRoleHolder() { - mViewModel.getLiveData().addRoleHolder(mRoleName, mPackageName, requireContext()); + mViewModel.getLiveData().addRoleHolderAsUser(mRoleName, mPackageName, + Process.myUserHandle(), requireContext()); } private void setResultOkAndFinish() { diff --git a/src/com/android/packageinstaller/role/ui/RoleListLiveData.java b/src/com/android/packageinstaller/role/ui/RoleListLiveData.java index f76fc9736..c4435a77d 100644 --- a/src/com/android/packageinstaller/role/ui/RoleListLiveData.java +++ b/src/com/android/packageinstaller/role/ui/RoleListLiveData.java @@ -20,7 +20,6 @@ import android.app.role.OnRoleHoldersChangedListener; import android.app.role.RoleManager; import android.content.Context; import android.content.pm.ApplicationInfo; -import android.os.Process; import android.os.UserHandle; import android.util.ArrayMap; import android.util.Log; @@ -45,10 +44,14 @@ public class RoleListLiveData extends AsyncTaskLiveData> private static final String LOG_TAG = RoleListLiveData.class.getSimpleName(); private final boolean mExclusive; + @NonNull + private final UserHandle mUser; + @NonNull private final Context mContext; - public RoleListLiveData(boolean exclusive, @NonNull Context context) { + public RoleListLiveData(boolean exclusive, @NonNull UserHandle user, @NonNull Context context) { mExclusive = exclusive; + mUser = user; mContext = context; } @@ -57,16 +60,14 @@ public class RoleListLiveData extends AsyncTaskLiveData> loadValue(); RoleManager roleManager = mContext.getSystemService(RoleManager.class); - // TODO: STOPSHIP: Handle work profile? roleManager.addOnRoleHoldersChangedListenerAsUser(mContext.getMainExecutor(), this, - Process.myUserHandle()); + mUser); } @Override protected void onInactive() { RoleManager roleManager = mContext.getSystemService(RoleManager.class); - // TODO: STOPSHIP: Handle work profile? - roleManager.removeOnRoleHoldersChangedListenerAsUser(this, Process.myUserHandle()); + roleManager.removeOnRoleHoldersChangedListenerAsUser(this, mUser); } @Override @@ -74,6 +75,7 @@ public class RoleListLiveData extends AsyncTaskLiveData> loadValue(); } + @NonNull @Override @WorkerThread protected List loadValueInBackground() { @@ -89,22 +91,23 @@ public class RoleListLiveData extends AsyncTaskLiveData> continue; } - if (role.getQualifyingPackages(mContext).isEmpty()) { + if (role.getQualifyingPackagesAsUser(mUser, mContext).isEmpty()) { continue; } List holderApplicationInfos = new ArrayList<>(); - List holderPackageNames = roleManager.getRoleHolders(role.getName()); + List holderPackageNames = roleManager.getRoleHoldersAsUser(role.getName(), + mUser); int holderPackageNamesSize = holderPackageNames.size(); for (int holderPackageNamesIndex = 0; holderPackageNamesIndex < holderPackageNamesSize; holderPackageNamesIndex++) { String holderPackageName = holderPackageNames.get(holderPackageNamesIndex); - ApplicationInfo holderApplicationInfo = PackageUtils.getApplicationInfo( - holderPackageName, mContext); + ApplicationInfo holderApplicationInfo = PackageUtils.getApplicationInfoAsUser( + holderPackageName, mUser, mContext); if (holderApplicationInfo == null) { - Log.w(LOG_TAG, "Cannot get ApplicationInfo for application, skipping: " - + holderPackageName); + Log.w(LOG_TAG, "Cannot get ApplicationInfo for application, package name: " + + holderPackageName + ", user id: " + mUser.getIdentifier()); continue; } holderApplicationInfos.add(holderApplicationInfo); diff --git a/src/com/android/packageinstaller/role/ui/RoleListViewModel.java b/src/com/android/packageinstaller/role/ui/RoleListViewModel.java index de29928de..4d756dc9d 100644 --- a/src/com/android/packageinstaller/role/ui/RoleListViewModel.java +++ b/src/com/android/packageinstaller/role/ui/RoleListViewModel.java @@ -17,29 +17,92 @@ package com.android.packageinstaller.role.ui; import android.app.Application; +import android.content.Context; +import android.os.Process; +import android.os.UserHandle; +import android.os.UserManager; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.lifecycle.AndroidViewModel; import androidx.lifecycle.ViewModel; import androidx.lifecycle.ViewModelProvider; +import java.util.List; +import java.util.Objects; + /** * {@link ViewModel} for a list of roles. */ public class RoleListViewModel extends AndroidViewModel { @NonNull - private final RoleListLiveData mLiveData; + private final UserHandle mUser; + @NonNull + private final RoleListLiveData mUserLiveData; + @Nullable + private final UserHandle mWorkProfile; + @Nullable + private final RoleListLiveData mWorkLiveData; public RoleListViewModel(boolean exclusive, @NonNull Application application) { super(application); - mLiveData = new RoleListLiveData(exclusive, application); + mUser = Process.myUserHandle(); + mUserLiveData = new RoleListLiveData(exclusive, mUser, application); + mWorkProfile = getWorkProfile(application); + mWorkLiveData = mWorkProfile != null ? new RoleListLiveData(exclusive, mWorkProfile, + application) : null; + } + + @Nullable + private static UserHandle getWorkProfile(@NonNull Context context) { + UserManager userManager = context.getSystemService(UserManager.class); + List profiles = userManager.getUserProfiles(); + UserHandle user = Process.myUserHandle(); + + int profilesSize = profiles.size(); + for (int i = 0; i < profilesSize; i++) { + UserHandle profile = profiles.get(i); + + if (Objects.equals(profile, user)) { + continue; + } + if (!userManager.isManagedProfile(profile.getIdentifier())) { + continue; + } + return profile; + } + return null; + } + + @NonNull + public UserHandle getUser() { + return mUser; } @NonNull public RoleListLiveData getLiveData() { - return mLiveData; + return mUserLiveData; + } + + /** + * Check whether the user has a work profile. + * + * @return whether the user has a work profile. + */ + public boolean hasWorkProfile() { + return mWorkProfile != null; + } + + @Nullable + public UserHandle getWorkProfile() { + return mWorkProfile; + } + + @Nullable + public RoleListLiveData getWorkLiveData() { + return mWorkLiveData; } /** diff --git a/src/com/android/packageinstaller/role/ui/RoleLiveData.java b/src/com/android/packageinstaller/role/ui/RoleLiveData.java index 2b1117df5..55c3ccbc1 100644 --- a/src/com/android/packageinstaller/role/ui/RoleLiveData.java +++ b/src/com/android/packageinstaller/role/ui/RoleLiveData.java @@ -20,7 +20,6 @@ import android.app.role.OnRoleHoldersChangedListener; import android.app.role.RoleManager; import android.content.Context; import android.content.pm.ApplicationInfo; -import android.os.Process; import android.os.UserHandle; import android.util.Log; @@ -42,11 +41,16 @@ public class RoleLiveData extends AsyncTaskLiveData private static final String LOG_TAG = RoleLiveData.class.getSimpleName(); + @NonNull private final Role mRole; + @NonNull + private final UserHandle mUser; + @NonNull private final Context mContext; - public RoleLiveData(@NonNull Role role, @NonNull Context context) { + public RoleLiveData(@NonNull Role role, @NonNull UserHandle user, @NonNull Context context) { mRole = role; + mUser = user; mContext = context; } @@ -55,16 +59,13 @@ public class RoleLiveData extends AsyncTaskLiveData loadValue(); RoleManager roleManager = mContext.getSystemService(RoleManager.class); - // TODO: STOPSHIP: Handle work profile? - roleManager.addOnRoleHoldersChangedListenerAsUser(mContext.getMainExecutor(), this, - Process.myUserHandle()); + roleManager.addOnRoleHoldersChangedListenerAsUser(mContext.getMainExecutor(), this, mUser); } @Override protected void onInactive() { RoleManager roleManager = mContext.getSystemService(RoleManager.class); - // TODO: STOPSHIP: Handle work profile? - roleManager.removeOnRoleHoldersChangedListenerAsUser(this, Process.myUserHandle()); + roleManager.removeOnRoleHoldersChangedListenerAsUser(this, mUser); } @Override @@ -75,14 +76,14 @@ public class RoleLiveData extends AsyncTaskLiveData @Override @WorkerThread protected RoleInfo loadValueInBackground() { - List qualifyingPackageNames = mRole.getQualifyingPackages(mContext); + List qualifyingPackageNames = mRole.getQualifyingPackagesAsUser(mUser, mContext); List qualifyingApplicationInfos = new ArrayList<>(); int qualifyingPackageNamesSize = qualifyingPackageNames.size(); for (int i = 0; i < qualifyingPackageNamesSize; i++) { String qualifyingPackageName = qualifyingPackageNames.get(i); - ApplicationInfo qualifyingApplicationInfo = PackageUtils.getApplicationInfo( - qualifyingPackageName, mContext); + ApplicationInfo qualifyingApplicationInfo = PackageUtils.getApplicationInfoAsUser( + qualifyingPackageName, mUser, mContext); if (qualifyingApplicationInfo == null) { Log.w(LOG_TAG, "Cannot get ApplicationInfo for application, skipping: " + qualifyingPackageName); @@ -92,7 +93,7 @@ public class RoleLiveData extends AsyncTaskLiveData } RoleManager roleManager = mContext.getSystemService(RoleManager.class); - List holderPackageNames = roleManager.getRoleHolders(mRole.getName()); + List holderPackageNames = roleManager.getRoleHoldersAsUser(mRole.getName(), mUser); return new RoleInfo(qualifyingApplicationInfos, holderPackageNames); } diff --git a/src/com/android/packageinstaller/role/utils/PackageUtils.java b/src/com/android/packageinstaller/role/utils/PackageUtils.java index d3fe999e7..912355ec8 100644 --- a/src/com/android/packageinstaller/role/utils/PackageUtils.java +++ b/src/com/android/packageinstaller/role/utils/PackageUtils.java @@ -20,6 +20,7 @@ import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; +import android.os.UserHandle; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -73,4 +74,26 @@ public final class PackageUtils { return null; } } + + /** + * Retrieve the {@link ApplicationInfo} of an application. + * + * @param packageName the package name of the application + * @param user the user of the application + * @param context the {@code Context} to retrieve system services + * + * @return the {@link ApplicationInfo} of the application, or {@code null} if not found + */ + @Nullable + public static ApplicationInfo getApplicationInfoAsUser(@NonNull String packageName, + @NonNull UserHandle user, @NonNull Context context) { + PackageManager packageManager = context.getPackageManager(); + try { + return packageManager.getApplicationInfoAsUser(packageName, + PackageManager.MATCH_DIRECT_BOOT_AWARE + | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, user); + } catch (PackageManager.NameNotFoundException e) { + return null; + } + } } -- GitLab From cacf2f7529be5be2e815eb20cbc5c2619cf638ce Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Wed, 12 Dec 2018 16:18:08 -0800 Subject: [PATCH 198/701] Color LocationAccessNotificaiton with system color Test: Looked at notification Change-Id: Ia777c4c7e81a875ec2f3415ba5fa5cb51cb12417 Fixes: 120795278 --- res/drawable/ic_signal_location.xml | 4 ++-- .../permission/service/LocationAccessCheck.java | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/res/drawable/ic_signal_location.xml b/res/drawable/ic_signal_location.xml index db8f1afbe..0e0d8d5d2 100644 --- a/res/drawable/ic_signal_location.xml +++ b/res/drawable/ic_signal_location.xml @@ -21,9 +21,9 @@ android:viewportWidth="24.0" android:viewportHeight="24.0"> \ No newline at end of file diff --git a/src/com/android/packageinstaller/permission/service/LocationAccessCheck.java b/src/com/android/packageinstaller/permission/service/LocationAccessCheck.java index d015bf6b5..43fdd7ebe 100644 --- a/src/com/android/packageinstaller/permission/service/LocationAccessCheck.java +++ b/src/com/android/packageinstaller/permission/service/LocationAccessCheck.java @@ -541,6 +541,7 @@ public class LocationAccessCheck extends JobService { R.string.background_location_access_reminder_notification_content))) .setSmallIcon(R.drawable.ic_signal_location) .setLargeIcon(pkgIconBmp) + .setColor(getColor(android.R.color.system_notification_accent_color)) .setAutoCancel(true) .setDeleteIntent(getBroadcast(this, 0, deleteIntent, FLAG_ONE_SHOT | FLAG_UPDATE_CURRENT)) -- GitLab From 4ea2fc6d0f9cc9a88b7cd6c3e164edecf1e20064 Mon Sep 17 00:00:00 2001 From: tmfang Date: Thu, 13 Dec 2018 10:53:22 +0800 Subject: [PATCH 199/701] Fix some libraries name of SettingsLib Since SettingsLib changes some libraries name, we need to also change name here. Change-Id: I444e09fb9639877fc1f533d7929ce6ed43762fbf Fixes: 120706174 Test: Rebuild --- Android.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Android.mk b/Android.mk index 48b0737aa..33b059039 100644 --- a/Android.mk +++ b/Android.mk @@ -30,8 +30,8 @@ LOCAL_STATIC_ANDROID_LIBRARIES += \ SettingsLibAppPreference \ SettingsLibSearchWidget \ SettingsLibSettingsSpinner \ - SettingsLayoutPreference \ - ActionButtonsPreference + SettingsLibLayoutPreference \ + SettingsLibActionButtonsPreference LOCAL_STATIC_JAVA_LIBRARIES := \ androidx.annotation_annotation -- GitLab From c2fa085129b53311597f0f7003d2c37c3749e0a0 Mon Sep 17 00:00:00 2001 From: Brad Stenning Date: Wed, 12 Dec 2018 17:40:11 -0800 Subject: [PATCH 200/701] Load the icon from the permission group using the correct context Bug: 112594279 Test: deploy car build and check Change-Id: I36e1d27fadbfeb97c6ddeb1e2d19229c49430faf (cherry picked from commit 31344bfda267d180290d559937266ad4414cc177) --- .../permission/ui/auto/AppPermissionsFragment.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/com/android/packageinstaller/permission/ui/auto/AppPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/auto/AppPermissionsFragment.java index 3d65e9f72..2e2948f89 100644 --- a/src/com/android/packageinstaller/permission/ui/auto/AppPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/auto/AppPermissionsFragment.java @@ -24,6 +24,7 @@ import android.content.Context; import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; +import android.graphics.drawable.Drawable; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; @@ -174,8 +175,9 @@ public final class AppPermissionsFragment extends Fragment{ PermissionLineItem(AppPermissionGroup permissionGroup, Context context) { super(context); setTitle(permissionGroup.getLabel().toString()); - setPrimaryActionIcon(permissionGroup.getIconResId(), - TextListItem.PRIMARY_ACTION_ICON_SIZE_SMALL); + Drawable icon = Utils.loadDrawable(context.getPackageManager(), + permissionGroup.getIconPkg(), permissionGroup.getIconResId()); + setPrimaryActionIcon(icon, TextListItem.PRIMARY_ACTION_ICON_SIZE_SMALL); setSwitch( permissionGroup.areRuntimePermissionsGranted(), /* showDivider= */ false, -- GitLab From be0d37e202139c798468ccc7162c3246966cf684 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Thu, 13 Dec 2018 10:43:32 -0800 Subject: [PATCH 201/701] Fix more truncated app label issues. While I'm at it, fix a bug with the new app header while we wait for the proper fix to merge. Test: See untruncated app label. Change-Id: I7094ec3b4b0a9723ea482b88d6b65766572e88e9 --- res/values/dimens.xml | 2 +- .../permission/ui/handheld/AppPermissionUsageFragment.java | 3 +-- .../permission/ui/handheld/AppPermissionsFragment.java | 4 +--- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/res/values/dimens.xml b/res/values/dimens.xml index cbeb646c7..dc0ba8b82 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -54,5 +54,5 @@ 12dp 8dp - 120dp + 125dp diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java index 7c2a91578..82b84a007 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java @@ -118,8 +118,7 @@ public class AppPermissionUsageFragment extends SettingsWithButtonHeader { ApplicationInfo appInfo = mAppPermissions.getPackageInfo().applicationInfo; Drawable icon = IconDrawableFactory.getBadgedIcon(getActivity(), appInfo, UserHandle.getUserHandleForUid(appInfo.uid)); - CharSequence label = appInfo.loadLabel(getActivity().getPackageManager()); - setHeader(icon, label); + setHeader(icon, Utils.getFullAppLabel(appInfo, getContext())); } } diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java index a9063936a..78f3a086f 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java @@ -160,13 +160,11 @@ public final class AppPermissionsFragment extends SettingsWithButtonHeader { private static void bindUi(SettingsWithButtonHeader fragment, PackageInfo packageInfo) { Activity activity = fragment.getActivity(); - PackageManager pm = activity.getPackageManager(); ApplicationInfo appInfo = packageInfo.applicationInfo; Drawable icon = IconDrawableFactory.getBadgedIcon(activity, appInfo, UserHandle.getUserHandleForUid(appInfo.uid)); - CharSequence label = appInfo.loadLabel(pm); - fragment.setHeader(icon, label); + fragment.setHeader(icon, Utils.getFullAppLabel(appInfo, activity)); ActionBar ab = activity.getActionBar(); if (ab != null) { -- GitLab From 72852da650d80503d78e909975a6dde1ac156123 Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Thu, 13 Dec 2018 11:47:44 -0800 Subject: [PATCH 202/701] Exclude Android System from being qualified for a role. This change excludes the Android System from being qualified for a role. Android System used to qualify for the dialer role in work profile because when resolving intent as a work profile user, the Android System offers IntentForwarderActivity as a potential choice and was thus qualified according to the dialer role definition. Bug: 110557011 Test: manual Change-Id: Id8a5123607150b7df452f8ff61d17d46e9986201 --- src/com/android/packageinstaller/role/model/Role.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/com/android/packageinstaller/role/model/Role.java b/src/com/android/packageinstaller/role/model/Role.java index 9527d0eed..8b4aac37d 100644 --- a/src/com/android/packageinstaller/role/model/Role.java +++ b/src/com/android/packageinstaller/role/model/Role.java @@ -52,6 +52,8 @@ public class Role { private static final String LOG_TAG = Role.class.getSimpleName(); + private static final String PACKAGE_NAME_ANDROID_SYSTEM = "android"; + /** * The name of this role. Must be unique. */ @@ -149,6 +151,9 @@ public class Role { * @return whether the package is qualified for a role */ public boolean isPackageQualified(@NonNull String packageName, @NonNull Context context) { + if (Objects.equals(packageName, PACKAGE_NAME_ANDROID_SYSTEM)) { + return false; + } int requiredComponentsSize = mRequiredComponents.size(); for (int i = 0; i < requiredComponentsSize; i++) { RequiredComponent requiredComponent = mRequiredComponents.get(i); @@ -185,6 +190,9 @@ public class Role { ComponentName componentName = qualifyingComponents.get(qualifyingComponentsIndex); String packageName = componentName.getPackageName(); + if (Objects.equals(packageName, PACKAGE_NAME_ANDROID_SYSTEM)) { + continue; + } Integer componentCount = packageComponentCountMap.get(packageName); packageComponentCountMap.put(packageName, componentCount == null ? 1 : componentCount + 1); -- GitLab From 6ffbdf1ca988b8eb654d78fd824e4e92a003fc6f Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Fri, 14 Dec 2018 08:15:55 -0800 Subject: [PATCH 203/701] Remove workaround for strangely-sized component. When adding the new app info header, I had to manually specify its height to avoid it taking up the whole screen. That bug has been fixed, so I can remove my workaround. I'm also making its margins more consistent with other uses of this header. Test: Visually inspect header and see it similar to existing ones. Change-Id: I623b68a2d32593c8e31e359717272dfa6cc0baea --- res/layout/button_header.xml | 12 +----------- res/values/dimens.xml | 2 -- .../ui/handheld/SettingsWithButtonHeader.java | 3 +++ 3 files changed, 4 insertions(+), 13 deletions(-) diff --git a/res/layout/button_header.xml b/res/layout/button_header.xml index 550b1da50..70435066b 100644 --- a/res/layout/button_header.xml +++ b/res/layout/button_header.xml @@ -21,19 +21,11 @@ android:orientation="vertical" android:gravity="center" > - - - - - + X @@ -41,8 +33,6 @@ diff --git a/res/values/dimens.xml b/res/values/dimens.xml index dc0ba8b82..7b856fe59 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -53,6 +53,4 @@ 12dp 8dp - - 125dp diff --git a/src/com/android/packageinstaller/permission/ui/handheld/SettingsWithButtonHeader.java b/src/com/android/packageinstaller/permission/ui/handheld/SettingsWithButtonHeader.java index 719596b97..d7f1a1ef9 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/SettingsWithButtonHeader.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/SettingsWithButtonHeader.java @@ -80,6 +80,9 @@ public abstract class SettingsWithButtonHeader extends PermissionsFrameFragment TextView appName = header.requireViewById(R.id.entity_header_title); appName.setText(mLabel); + header.requireViewById(R.id.entity_header_summary).setVisibility(View.GONE); + header.requireViewById(R.id.entity_header_second_summary).setVisibility(View.GONE); + Button button1 = header.requireViewById(R.id.button1); button1.setText(R.string.launch_app); setButtonIcon(button1, R.drawable.ic_open); -- GitLab From e8c811aa1c05c7c2fe3fb695686a8b63b172fda9 Mon Sep 17 00:00:00 2001 From: Tyler Gunn Date: Thu, 1 Nov 2018 16:36:14 -0700 Subject: [PATCH 204/701] Add Telecom specific roles. CAR_MODE_DIALER_APP (for automotive apps) - requires IncallService which declares IN_CALL_SERVICE_CAR_MODE_UI true. CALL_COMPANION_APP (for wearable companion apps) - requires InCallService which doesn't declare IN_CALL_SERVICE_UI or IN_CALL_SERVICE_CAR_MODE_UI. CALL_SCREENING_APP - requires CallScreeningService to be defined. PROXY_CALLING_APP - requires CallRedirectionService to be defined. Test: Manual Bug: 63966743 Change-Id: I8285d402522f45fe4832b1475f3fec00668186f8 --- res/values/strings.xml | 8 +++++ res/xml/roles.xml | 79 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) diff --git a/res/values/strings.xml b/res/values/strings.xml index d84c07647..ff6285693 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -427,6 +427,14 @@ Phone app + + Car mode phone app + + Call screening app + + Call companion app + + Proxy calling app SMS app diff --git a/res/xml/roles.xml b/res/xml/roles.xml index 8ced871ff..454f405b9 100644 --- a/res/xml/roles.xml +++ b/res/xml/roles.xml @@ -77,6 +77,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -91,6 +160,16 @@ + + + + + + + -- GitLab From 95946394247b766dd0085e82ba01a70f4002021b Mon Sep 17 00:00:00 2001 From: Eugene Susla Date: Wed, 12 Dec 2018 13:43:51 -0800 Subject: [PATCH 205/701] On role revocation, don't revoke appops/perms for other held roles Test: atest android.app.role.cts.RoleManagerTest#revokeSingleRoleThenEnsureOtherRolesAppopsIntact Change-Id: Ifd27d703f878789fe68f128e05d0dcbc570029b4 --- .../packageinstaller/role/model/Role.java | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/src/com/android/packageinstaller/role/model/Role.java b/src/com/android/packageinstaller/role/model/Role.java index 8b4aac37d..d095c64fa 100644 --- a/src/com/android/packageinstaller/role/model/Role.java +++ b/src/com/android/packageinstaller/role/model/Role.java @@ -17,6 +17,7 @@ package com.android.packageinstaller.role.model; import android.app.ActivityManager; +import android.app.role.RoleManager; import android.content.ComponentName; import android.content.Context; import android.content.pm.ApplicationInfo; @@ -158,6 +159,8 @@ public class Role { for (int i = 0; i < requiredComponentsSize; i++) { RequiredComponent requiredComponent = mRequiredComponents.get(i); if (requiredComponent.getQualifyingComponentForPackage(packageName, context) == null) { + Log.w(LOG_TAG, packageName + " not qualified for " + mName + + " due to missing " + requiredComponent); return false; } } @@ -264,13 +267,30 @@ public class Role { */ public void revoke(@NonNull String packageName, boolean mayKillApp, boolean overrideSystemFixedPermissions, @NonNull Context context) { - boolean permissionOrAppOpChanged = Permissions.revoke(packageName, mPermissions, + List remainingRolesHeld = context.getSystemService(RoleManager.class) + .getHeldRolesFromController(packageName); + remainingRolesHeld.remove(mName); + + // Revoke permissions + ArrayMap roles = Roles.getRoles(context); + List permissionsToRevoke = new ArrayList<>(mPermissions); + int size = remainingRolesHeld.size(); + for (int i = 0; i < size; i++) { + String remainingRole = remainingRolesHeld.get(i); + permissionsToRevoke.removeAll(roles.get(remainingRole).getPermissions()); + } + boolean permissionOrAppOpChanged = Permissions.revoke(packageName, permissionsToRevoke, overrideSystemFixedPermissions, context); - int appOpsSize = mAppOps.size(); + // Revoke appops + List appOpsToRevoke = new ArrayList<>(mAppOps); + size = remainingRolesHeld.size(); + for (int i = 0; i < size; i++) { + appOpsToRevoke.removeAll(roles.get(remainingRolesHeld.get(i)).getAppOps()); + } + int appOpsSize = appOpsToRevoke.size(); for (int i = 0; i < appOpsSize; i++) { - AppOp appOp = mAppOps.get(i); - permissionOrAppOpChanged |= appOp.revoke(packageName, context); + permissionOrAppOpChanged |= appOpsToRevoke.get(i).revoke(packageName, context); } // TODO: STOPSHIP: Revoke preferred activities? -- GitLab From 6751fbd94f9a29a340b93488f2df2de585368250 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Fri, 14 Dec 2018 12:22:15 -0800 Subject: [PATCH 206/701] Fix crashes when entering battery saver mode. A number of the Permissions Controller screens crash when enabling battery saver mode while they are open. This fixes them by properly checking for a null Activity. Change-Id: I147028bd3cfaaf28cd3a68c8c9c51a05756fc199 Fixes: 117661500 Test: Enable Battery Saver mode in many screens and see no crash. --- .../permission/ui/handheld/ManagePermissionsFragment.java | 2 +- .../permission/ui/handheld/PermissionAppsFragment.java | 2 +- .../permission/ui/handheld/PermissionUsageFragment.java | 4 ++++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/com/android/packageinstaller/permission/ui/handheld/ManagePermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/ManagePermissionsFragment.java index 28dd40e71..de4e89e55 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/ManagePermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/ManagePermissionsFragment.java @@ -107,7 +107,7 @@ abstract class ManagePermissionsFragment extends PermissionsFrameFragment */ protected PreferenceScreen updatePermissionsUi(boolean addSystemPermissions) { Context context = getPreferenceManager().getContext(); - if (context == null) { + if (context == null || getActivity() == null) { return null; } diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java index 93b84fb49..c7be9a810 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java @@ -185,7 +185,7 @@ public final class PermissionAppsFragment extends PermissionsFrameFragment imple public void onPermissionsLoaded(PermissionApps permissionApps) { Context context = getPreferenceManager().getContext(); - if (context == null) { + if (context == null || getActivity() == null) { return; } diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java index 47c2f12d9..d68e45824 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java @@ -253,6 +253,10 @@ public class PermissionUsageFragment extends PermissionsFrameFragment implements } private void addPreferences() { + if (getActivity() == null) { + return; + } + PreferenceScreen screen = getPreferenceScreen(); if (screen == null) { Context context = getPreferenceManager().getContext(); -- GitLab From 1da06cd0b762033234d1f5966b0672de327650d2 Mon Sep 17 00:00:00 2001 From: Florian Mayer Date: Mon, 17 Dec 2018 10:28:37 +0000 Subject: [PATCH 207/701] Revert "Add work profile support for the new Default apps UI." This reverts commit 9ce4a3ce1cbe18ed4ec82d4f0a076c89343a598b. Reason for revert: This broke mainline_modules-userdebug. packages/apps/PermissionController/src/com/android/packageinstaller/role/model/RequiredActivity.java:47: error: cannot find symbol return packageManager.queryIntentActivitiesAsUser(intent, flags, user); ^ symbol: method queryIntentActivitiesAsUser(Intent,int,UserHandle) location: variable packageManager of type PackageManager packages/apps/PermissionController/src/com/android/packageinstaller/role/model/RequiredContentProvider.java:47: error: cannot find symbol return packageManager.queryIntentContentProvidersAsUser(intent, flags, user); ^ symbol: method queryIntentContentProvidersAsUser(Intent,int,UserHandle) location: variable packageManager of type PackageManager packages/apps/PermissionController/src/com/android/packageinstaller/role/model/RequiredService.java:47: error: cannot find symbol return packageManager.queryIntentServicesAsUser(intent, flags, user); ^ symbol: method queryIntentServicesAsUser(Intent,int,UserHandle) location: variable packageManager of type PackageManager packages/apps/PermissionController/src/com/android/packageinstaller/role/utils/PackageUtils.java:92: error: cannot find symbol return packageManager.getApplicationInfoAsUser(packageName, ^ symbol: method getApplicationInfoAsUser(String,int,UserHandle) location: variable packageManager of type PackageManager 4 errors Change-Id: Ia9c0e6ed2bd04f9656cf5de50b0d3cac190e49d0 --- res/values/strings.xml | 3 - .../role/model/PreferredActivity.java | 4 +- .../role/model/RequiredActivity.java | 7 +- .../role/model/RequiredBroadcastReceiver.java | 7 +- .../role/model/RequiredComponent.java | 27 +++---- .../role/model/RequiredContentProvider.java | 7 +- .../role/model/RequiredService.java | 7 +- .../packageinstaller/role/model/Role.java | 11 +-- .../role/ui/AddRoleHolderStateLiveData.java | 7 +- .../role/ui/DefaultAppActivity.java | 15 +--- .../role/ui/DefaultAppFragment.java | 19 ++--- .../role/ui/DefaultAppListFragment.java | 80 ++++--------------- .../role/ui/DefaultAppViewModel.java | 15 +--- .../role/ui/RequestRoleFragment.java | 4 +- .../role/ui/RoleListLiveData.java | 27 +++---- .../role/ui/RoleListViewModel.java | 69 +--------------- .../role/ui/RoleLiveData.java | 23 +++--- .../role/utils/PackageUtils.java | 23 ------ 18 files changed, 86 insertions(+), 269 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index fcf8b3b0a..9474e1a15 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -426,9 +426,6 @@ No default apps - - Default for work - None diff --git a/src/com/android/packageinstaller/role/model/PreferredActivity.java b/src/com/android/packageinstaller/role/model/PreferredActivity.java index 75553d5b4..ad96e45b2 100644 --- a/src/com/android/packageinstaller/role/model/PreferredActivity.java +++ b/src/com/android/packageinstaller/role/model/PreferredActivity.java @@ -20,7 +20,6 @@ import android.content.ComponentName; import android.content.Context; import android.content.IntentFilter; import android.content.pm.PackageManager; -import android.os.Process; import androidx.annotation.NonNull; @@ -69,8 +68,7 @@ public class PreferredActivity { */ public void configure(@NonNull String packageName, @NonNull Context context) { IntentFilter intentFilter = mActivity.getIntentFilterData().createIntentFilter(); - List activities = mActivity.getQualifyingComponentsAsUser( - Process.myUserHandle(), context); + List activities = mActivity.getQualifyingComponents(context); ComponentName packageActivity = mActivity.getQualifyingComponentForPackage( packageName, context); // TODO: STOPSHIP: Race condition, what if packageActivity became null? Just don't crash? diff --git a/src/com/android/packageinstaller/role/model/RequiredActivity.java b/src/com/android/packageinstaller/role/model/RequiredActivity.java index 742e7be97..b39bbd1d5 100644 --- a/src/com/android/packageinstaller/role/model/RequiredActivity.java +++ b/src/com/android/packageinstaller/role/model/RequiredActivity.java @@ -22,7 +22,6 @@ import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.Bundle; -import android.os.UserHandle; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -41,10 +40,10 @@ public class RequiredActivity extends RequiredComponent { @NonNull @Override - protected List queryIntentComponentsAsUser(@NonNull Intent intent, int flags, - @NonNull UserHandle user, @NonNull Context context) { + protected List queryIntentComponents(@NonNull Intent intent, int flags, + @NonNull Context context) { PackageManager packageManager = context.getPackageManager(); - return packageManager.queryIntentActivitiesAsUser(intent, flags, user); + return packageManager.queryIntentActivities(intent, flags); } @NonNull diff --git a/src/com/android/packageinstaller/role/model/RequiredBroadcastReceiver.java b/src/com/android/packageinstaller/role/model/RequiredBroadcastReceiver.java index 37a8f1ca1..21eb670af 100644 --- a/src/com/android/packageinstaller/role/model/RequiredBroadcastReceiver.java +++ b/src/com/android/packageinstaller/role/model/RequiredBroadcastReceiver.java @@ -22,7 +22,6 @@ import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.Bundle; -import android.os.UserHandle; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -41,10 +40,10 @@ public class RequiredBroadcastReceiver extends RequiredComponent { @NonNull @Override - protected List queryIntentComponentsAsUser(@NonNull Intent intent, int flags, - @NonNull UserHandle user, @NonNull Context context) { + protected List queryIntentComponents(@NonNull Intent intent, int flags, + @NonNull Context context) { PackageManager packageManager = context.getPackageManager(); - return packageManager.queryBroadcastReceiversAsUser(intent, flags, user); + return packageManager.queryBroadcastReceivers(intent, flags); } @NonNull diff --git a/src/com/android/packageinstaller/role/model/RequiredComponent.java b/src/com/android/packageinstaller/role/model/RequiredComponent.java index 951d2a02c..e810af696 100644 --- a/src/com/android/packageinstaller/role/model/RequiredComponent.java +++ b/src/com/android/packageinstaller/role/model/RequiredComponent.java @@ -22,8 +22,6 @@ import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.Bundle; -import android.os.Process; -import android.os.UserHandle; import android.util.ArraySet; import android.util.Log; @@ -98,8 +96,8 @@ public abstract class RequiredComponent { @Nullable public ComponentName getQualifyingComponentForPackage(@NonNull String packageName, @NonNull Context context) { - List componentNames = getQualifyingComponentsInternal(packageName, - Process.myUserHandle(), context); + List componentNames = getQualifyingComponents(packageName, + context); return !componentNames.isEmpty() ? componentNames.get(0) : null; } @@ -107,22 +105,20 @@ public abstract class RequiredComponent { * Get the list of components that match this required component, at most one component per * package and ordered from best to worst. * - * @param user the user to get the qualifying components. * @param context the {@code Context} to retrieve system services * * @return the list of matching components * - * @see Role#getQualifyingPackagesAsUser(UserHandle, Context) + * @see Role#getQualifyingPackages(Context) */ @NonNull - public List getQualifyingComponentsAsUser(@NonNull UserHandle user, - @NonNull Context context) { - return getQualifyingComponentsInternal(null, user, context); + public List getQualifyingComponents(@NonNull Context context) { + return getQualifyingComponents(null, context); } @NonNull - private List getQualifyingComponentsInternal(@Nullable String packageName, - @NonNull UserHandle user, @NonNull Context context) { + private List getQualifyingComponents(@Nullable String packageName, + @NonNull Context context) { Intent intent = mIntentFilterData.createIntent(); if (packageName != null) { intent.setPackage(packageName); @@ -133,7 +129,7 @@ public abstract class RequiredComponent { if (hasMetaData) { flags |= PackageManager.GET_META_DATA; } - List resolveInfos = queryIntentComponentsAsUser(intent, flags, user, context); + List resolveInfos = queryIntentComponents(intent, flags, context); ArraySet componentPackageNames = new ArraySet<>(); List componentNames = new ArrayList<>(); @@ -186,15 +182,14 @@ public abstract class RequiredComponent { * to worst. * * @param intent the {@code Intent} to match against - * @param flags the flags for this query - * @param user the user for this query + * @param flags the flags to be used for this query * @param context the {@code Context} to retrieve system services * * @return the list of matching components */ @NonNull - protected abstract List queryIntentComponentsAsUser(@NonNull Intent intent, - int flags, @NonNull UserHandle user, @NonNull Context context); + protected abstract List queryIntentComponents(@NonNull Intent intent, int flags, + @NonNull Context context); /** * Get the {@code ComponentName} of a component. diff --git a/src/com/android/packageinstaller/role/model/RequiredContentProvider.java b/src/com/android/packageinstaller/role/model/RequiredContentProvider.java index 776c83997..eb0f5f079 100644 --- a/src/com/android/packageinstaller/role/model/RequiredContentProvider.java +++ b/src/com/android/packageinstaller/role/model/RequiredContentProvider.java @@ -22,7 +22,6 @@ import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.Bundle; -import android.os.UserHandle; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -41,10 +40,10 @@ public class RequiredContentProvider extends RequiredComponent { @NonNull @Override - protected List queryIntentComponentsAsUser(@NonNull Intent intent, int flags, - @NonNull UserHandle user, @NonNull Context context) { + protected List queryIntentComponents(@NonNull Intent intent, int flags, + @NonNull Context context) { PackageManager packageManager = context.getPackageManager(); - return packageManager.queryIntentContentProvidersAsUser(intent, flags, user); + return packageManager.queryIntentContentProviders(intent, flags); } @NonNull diff --git a/src/com/android/packageinstaller/role/model/RequiredService.java b/src/com/android/packageinstaller/role/model/RequiredService.java index 17fc5f079..9bab7b9f7 100644 --- a/src/com/android/packageinstaller/role/model/RequiredService.java +++ b/src/com/android/packageinstaller/role/model/RequiredService.java @@ -22,7 +22,6 @@ import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.Bundle; -import android.os.UserHandle; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -41,10 +40,10 @@ public class RequiredService extends RequiredComponent { @NonNull @Override - protected List queryIntentComponentsAsUser(@NonNull Intent intent, int flags, - @NonNull UserHandle user, @NonNull Context context) { + protected List queryIntentComponents(@NonNull Intent intent, int flags, + @NonNull Context context) { PackageManager packageManager = context.getPackageManager(); - return packageManager.queryIntentServicesAsUser(intent, flags, user); + return packageManager.queryIntentServices(intent, flags); } @NonNull diff --git a/src/com/android/packageinstaller/role/model/Role.java b/src/com/android/packageinstaller/role/model/Role.java index 200499d8d..9527d0eed 100644 --- a/src/com/android/packageinstaller/role/model/Role.java +++ b/src/com/android/packageinstaller/role/model/Role.java @@ -20,7 +20,6 @@ import android.app.ActivityManager; import android.content.ComponentName; import android.content.Context; import android.content.pm.ApplicationInfo; -import android.os.UserHandle; import android.util.ArrayMap; import android.util.Log; @@ -161,17 +160,15 @@ public class Role { } /** - * Get the list of packages that are qualified for this role, i.e. packages containing all the + * Get the set of packages that are qualified for this role, i.e. packages containing all the * required components. * - * @param user the user to get the qualifying packages. * @param context the {@code Context} to retrieve system services * * @return the set of packages that are qualified for this role */ @NonNull - public List getQualifyingPackagesAsUser(@NonNull UserHandle user, - @NonNull Context context) { + public List getQualifyingPackages(@NonNull Context context) { ArrayMap packageComponentCountMap = new ArrayMap<>(); int requiredComponentsSize = mRequiredComponents.size(); for (int requiredComponentsIndex = 0; requiredComponentsIndex < requiredComponentsSize; @@ -179,8 +176,8 @@ public class Role { RequiredComponent requiredComponent = mRequiredComponents.get(requiredComponentsIndex); // This returns at most one component per package. - List qualifyingComponents = - requiredComponent.getQualifyingComponentsAsUser(user, context); + List qualifyingComponents = requiredComponent.getQualifyingComponents( + context); int qualifyingComponentsSize = qualifyingComponents.size(); for (int qualifyingComponentsIndex = 0; qualifyingComponentsIndex < qualifyingComponentsSize; diff --git a/src/com/android/packageinstaller/role/ui/AddRoleHolderStateLiveData.java b/src/com/android/packageinstaller/role/ui/AddRoleHolderStateLiveData.java index 9606c6db4..45c0e8061 100644 --- a/src/com/android/packageinstaller/role/ui/AddRoleHolderStateLiveData.java +++ b/src/com/android/packageinstaller/role/ui/AddRoleHolderStateLiveData.java @@ -19,6 +19,7 @@ package com.android.packageinstaller.role.ui; import android.app.role.RoleManager; import android.app.role.RoleManagerCallback; import android.content.Context; +import android.os.Process; import android.os.UserHandle; import android.util.Log; @@ -49,11 +50,10 @@ public class AddRoleHolderStateLiveData extends LiveData { * * @param roleName the name of the role * @param packageName the package name of the application - * @param user the user to add the role holder for * @param context the {@code Context} to retrieve system services */ - public void addRoleHolderAsUser(@NonNull String roleName, @NonNull String packageName, - @NonNull UserHandle user, @NonNull Context context) { + public void addRoleHolder(@NonNull String roleName, @NonNull String packageName, + @NonNull Context context) { if (getValue() != STATE_IDLE) { Log.e(LOG_TAG, "Already (tried) adding package as role holder, requested role: " + roleName + ", requested package: " + packageName); @@ -64,6 +64,7 @@ public class AddRoleHolderStateLiveData extends LiveData { setValue(STATE_ADDING); RoleManager roleManager = context.getSystemService(RoleManager.class); + UserHandle user = Process.myUserHandle(); Executor executor = context.getMainExecutor(); roleManager.addRoleHolderAsUser(roleName, packageName, user, executor, new RoleManagerCallback() { diff --git a/src/com/android/packageinstaller/role/ui/DefaultAppActivity.java b/src/com/android/packageinstaller/role/ui/DefaultAppActivity.java index 67b2dc9b8..b1ae2c0a2 100644 --- a/src/com/android/packageinstaller/role/ui/DefaultAppActivity.java +++ b/src/com/android/packageinstaller/role/ui/DefaultAppActivity.java @@ -19,7 +19,6 @@ package com.android.packageinstaller.role.ui; import android.content.Context; import android.content.Intent; import android.os.Bundle; -import android.os.UserHandle; import android.util.Log; import androidx.annotation.NonNull; @@ -40,27 +39,21 @@ public class DefaultAppActivity extends FragmentActivity { * Create an intent for starting this activity. * * @param roleName the name of the role for the default app - * @param user the user for the default app * @param context the context to create the intent * * @return an intent to start this activity */ @NonNull - public static Intent createIntent(@NonNull String roleName, @NonNull UserHandle user, - @NonNull Context context) { + public static Intent createIntent(@NonNull String roleName, @NonNull Context context) { return new Intent(context, DefaultAppActivity.class) - .putExtra(DefaultAppFragment.EXTRA_ROLE_NAME, roleName) - .putExtra(Intent.EXTRA_USER, user); + .putExtra(DefaultAppFragment.EXTRA_ROLE_NAME, roleName); } @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - Intent intent = getIntent(); - String roleName = intent.getStringExtra(DefaultAppFragment.EXTRA_ROLE_NAME); - UserHandle user = intent.getParcelableExtra(Intent.EXTRA_USER); - + String roleName = getIntent().getStringExtra(DefaultAppFragment.EXTRA_ROLE_NAME); Role role = Roles.getRoles(this).get(roleName); if (role == null) { Log.e(LOG_TAG, "Unknown role: " + roleName); @@ -69,7 +62,7 @@ public class DefaultAppActivity extends FragmentActivity { } if (savedInstanceState == null) { - DefaultAppFragment fragment = DefaultAppFragment.newInstance(roleName, user); + DefaultAppFragment fragment = DefaultAppFragment.newInstance(roleName); getSupportFragmentManager().beginTransaction() .add(android.R.id.content, fragment) .commit(); diff --git a/src/com/android/packageinstaller/role/ui/DefaultAppFragment.java b/src/com/android/packageinstaller/role/ui/DefaultAppFragment.java index efa588787..a3497bc19 100644 --- a/src/com/android/packageinstaller/role/ui/DefaultAppFragment.java +++ b/src/com/android/packageinstaller/role/ui/DefaultAppFragment.java @@ -18,7 +18,6 @@ package com.android.packageinstaller.role.ui; import android.app.Activity; import android.content.Context; -import android.content.Intent; import android.content.pm.ApplicationInfo; import android.os.Bundle; import android.os.UserHandle; @@ -55,8 +54,6 @@ public class DefaultAppFragment extends SettingsFragment private String mRoleName; - private UserHandle mUser; - private Role mRole; private DefaultAppViewModel mViewModel; @@ -64,18 +61,15 @@ public class DefaultAppFragment extends SettingsFragment /** * Create a new instance of this fragment. * - * @param roleName the name of the role for the default app - * @param user the user for the default app + * @param roleName the name of the role to be managed * * @return a new instance of this fragment */ @NonNull - public static DefaultAppFragment newInstance(@NonNull String roleName, - @NonNull UserHandle user) { + public static DefaultAppFragment newInstance(@NonNull String roleName) { DefaultAppFragment fragment = new DefaultAppFragment(); Bundle arguments = new Bundle(); arguments.putString(EXTRA_ROLE_NAME, roleName); - arguments.putParcelable(Intent.EXTRA_USER, user); fragment.setArguments(arguments); return fragment; } @@ -84,9 +78,7 @@ public class DefaultAppFragment extends SettingsFragment public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - Bundle arguments = getArguments(); - mRoleName = arguments.getString(EXTRA_ROLE_NAME); - mUser = arguments.getParcelable(Intent.EXTRA_USER); + mRoleName = getArguments().getString(EXTRA_ROLE_NAME); } @Override @@ -97,7 +89,7 @@ public class DefaultAppFragment extends SettingsFragment mRole = Roles.getRoles(activity).get(mRoleName); activity.setTitle(mRole.getLabelResource()); - mViewModel = ViewModelProviders.of(this, new DefaultAppViewModel.Factory(mRole, mUser, + mViewModel = ViewModelProviders.of(this, new DefaultAppViewModel.Factory(mRole, activity.getApplication())).get(DefaultAppViewModel.class); mViewModel.getRoleLiveData().observe(this, this::onRoleInfoChanged); mViewModel.getAddRoleHolderStateLiveData().observe(this, this::onAddRoleHolderStateChanged); @@ -181,8 +173,7 @@ public class DefaultAppFragment extends SettingsFragment } String packageName = preference.getKey(); - addRoleHolderStateLiveData.addRoleHolderAsUser(mRoleName, packageName, mUser, - requireContext()); + addRoleHolderStateLiveData.addRoleHolder(mRoleName, packageName, requireContext()); return true; } } diff --git a/src/com/android/packageinstaller/role/ui/DefaultAppListFragment.java b/src/com/android/packageinstaller/role/ui/DefaultAppListFragment.java index 64a726737..ef82dd2ea 100644 --- a/src/com/android/packageinstaller/role/ui/DefaultAppListFragment.java +++ b/src/com/android/packageinstaller/role/ui/DefaultAppListFragment.java @@ -28,8 +28,6 @@ import androidx.annotation.Nullable; import androidx.annotation.StringRes; import androidx.lifecycle.ViewModelProviders; import androidx.preference.Preference; -import androidx.preference.PreferenceCategory; -import androidx.preference.PreferenceGroup; import androidx.preference.PreferenceManager; import androidx.preference.PreferenceScreen; @@ -48,8 +46,6 @@ public class DefaultAppListFragment extends SettingsFragment private static final String LOG_TAG = DefaultAppListFragment.class.getSimpleName(); - private static final String PREFERENCE_KEY_WORK_CATEGORY = "work_category"; - private RoleListViewModel mViewModel; /** @@ -68,10 +64,7 @@ public class DefaultAppListFragment extends SettingsFragment mViewModel = ViewModelProviders.of(this, new RoleListViewModel.Factory(true, requireActivity().getApplication())).get(RoleListViewModel.class); - mViewModel.getLiveData().observe(this, roleItems -> onRoleListChanged()); - if (mViewModel.hasWorkProfile()) { - mViewModel.getWorkLiveData().observe(this, roleItems -> onRoleListChanged()); - } + mViewModel.getLiveData().observe(this, this::onRoleListChanged); } @Override @@ -85,72 +78,27 @@ public class DefaultAppListFragment extends SettingsFragment return R.string.help_uri_default_apps; } - private void onRoleListChanged() { - List roleItems = mViewModel.getLiveData().getValue(); - if (roleItems == null) { - return; - } - boolean hasWorkProfile = mViewModel.hasWorkProfile(); - List workRoleItems = null; - if (hasWorkProfile) { - workRoleItems = mViewModel.getWorkLiveData().getValue(); - if (workRoleItems == null) { - return; - } - } - + private void onRoleListChanged(@NonNull List roleItems) { PreferenceManager preferenceManager = getPreferenceManager(); Context context = preferenceManager.getContext(); + PreferenceScreen preferenceScreen = getPreferenceScreen(); ArrayMap oldPreferences = new ArrayMap<>(); - PreferenceCategory oldWorkPreferenceCategory = null; - ArrayMap oldWorkPreferences = new ArrayMap<>(); if (preferenceScreen == null) { preferenceScreen = preferenceManager.createPreferenceScreen(context); setPreferenceScreen(preferenceScreen); } else { - oldWorkPreferenceCategory = (PreferenceCategory) preferenceScreen.findPreference( - PREFERENCE_KEY_WORK_CATEGORY); - if (oldWorkPreferenceCategory != null) { - clearPreferences(oldWorkPreferenceCategory, oldWorkPreferences); - preferenceScreen.removePreference(oldWorkPreferenceCategory); - } - clearPreferences(preferenceScreen, oldPreferences); - } + for (int i = preferenceScreen.getPreferenceCount() - 1; i >= 0; --i) { + Preference preference = preferenceScreen.getPreference(i); - addPreferences(preferenceScreen, roleItems, oldPreferences, this, mViewModel.getUser(), - context); - if (hasWorkProfile) { - PreferenceCategory workPreferenceCategory = oldWorkPreferenceCategory; - if (workPreferenceCategory == null) { - workPreferenceCategory = new PreferenceCategory(context); - workPreferenceCategory.setKey(PREFERENCE_KEY_WORK_CATEGORY); - workPreferenceCategory.setTitle(R.string.default_apps_for_work); + preferenceScreen.removePreference(preference); + oldPreferences.put(preference.getKey(), preference); } - preferenceScreen.addPreference(workPreferenceCategory); - addPreferences(workPreferenceCategory, workRoleItems, oldWorkPreferences, this, - mViewModel.getWorkProfile(), context); } - updateState(); - } - - private static void clearPreferences(@NonNull PreferenceGroup preferenceGroup, - @NonNull ArrayMap oldPreferences) { - for (int i = preferenceGroup.getPreferenceCount() - 1; i >= 0; --i) { - Preference Preference = preferenceGroup.getPreference(i); - - oldPreferences.put(Preference.getKey(), Preference); - } - } - - private static void addPreferences(@NonNull PreferenceGroup preferenceGroup, - @NonNull List roleItems, @NonNull ArrayMap oldPreferences, - @NonNull Preference.OnPreferenceClickListener listener, @NonNull UserHandle user, - @NonNull Context context) { int roleItemsSize = roleItems.size(); - for (int i = 0; i < roleItemsSize; i++) { - RoleItem roleItem = roleItems.get(i); + for (int roleItemsIndex = 0; roleItemsIndex < roleItemsSize; roleItemsIndex++) { + RoleItem roleItem = roleItems.get(roleItemsIndex); Role role = roleItem.getRole(); Preference preference = oldPreferences.get(role.getName()); @@ -160,8 +108,7 @@ public class DefaultAppListFragment extends SettingsFragment preference.setIconSpaceReserved(true); preference.setTitle(role.getLabelResource()); preference.setPersistent(false); - preference.setOnPreferenceClickListener(listener); - preference.getExtras().putParcelable(Intent.EXTRA_USER, user); + preference.setOnPreferenceClickListener(this); } List holderApplicationInfos = roleItem.getHolderApplicationInfos(); @@ -176,15 +123,16 @@ public class DefaultAppListFragment extends SettingsFragment } // TODO: Ordering? - preferenceGroup.addPreference(preference); + preferenceScreen.addPreference(preference); } + + updateState(); } @Override public boolean onPreferenceClick(@NonNull Preference preference) { String roleName = preference.getKey(); - UserHandle user = preference.getExtras().getParcelable(Intent.EXTRA_USER); - Intent intent = DefaultAppActivity.createIntent(roleName, user, requireContext()); + Intent intent = DefaultAppActivity.createIntent(roleName, requireContext()); startActivity(intent); return true; } diff --git a/src/com/android/packageinstaller/role/ui/DefaultAppViewModel.java b/src/com/android/packageinstaller/role/ui/DefaultAppViewModel.java index b51191a82..163327aa7 100644 --- a/src/com/android/packageinstaller/role/ui/DefaultAppViewModel.java +++ b/src/com/android/packageinstaller/role/ui/DefaultAppViewModel.java @@ -17,7 +17,6 @@ package com.android.packageinstaller.role.ui; import android.app.Application; -import android.os.UserHandle; import androidx.annotation.NonNull; import androidx.lifecycle.AndroidViewModel; @@ -38,11 +37,10 @@ public class DefaultAppViewModel extends AndroidViewModel { private final AddRoleHolderStateLiveData mAddRoleHolderStateLiveData = new AddRoleHolderStateLiveData(); - public DefaultAppViewModel(@NonNull Role role, @NonNull UserHandle user, - @NonNull Application application) { + public DefaultAppViewModel(@NonNull Role role, @NonNull Application application) { super(application); - mRoleLiveData = new RoleLiveData(role, user, application); + mRoleLiveData = new RoleLiveData(role, application); } @NonNull @@ -63,16 +61,11 @@ public class DefaultAppViewModel extends AndroidViewModel { @NonNull private Role mRole; - @NonNull - private UserHandle mUser; - @NonNull private Application mApplication; - public Factory(@NonNull Role role, @NonNull UserHandle user, - @NonNull Application application) { + public Factory(@NonNull Role role, @NonNull Application application) { mRole = role; - mUser = user; mApplication = application; } @@ -80,7 +73,7 @@ public class DefaultAppViewModel extends AndroidViewModel { @Override public T create(@NonNull Class modelClass) { //noinspection unchecked - return (T) new DefaultAppViewModel(mRole, mUser, mApplication); + return (T) new DefaultAppViewModel(mRole, mApplication); } } } diff --git a/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java b/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java index fd185e6cf..c9ed25090 100644 --- a/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java +++ b/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java @@ -25,7 +25,6 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.os.Bundle; -import android.os.Process; import android.text.Html; import android.util.Log; @@ -206,8 +205,7 @@ public class RequestRoleFragment extends DialogFragment { } private void addRoleHolder() { - mViewModel.getLiveData().addRoleHolderAsUser(mRoleName, mPackageName, - Process.myUserHandle(), requireContext()); + mViewModel.getLiveData().addRoleHolder(mRoleName, mPackageName, requireContext()); } private void setResultOkAndFinish() { diff --git a/src/com/android/packageinstaller/role/ui/RoleListLiveData.java b/src/com/android/packageinstaller/role/ui/RoleListLiveData.java index c4435a77d..f76fc9736 100644 --- a/src/com/android/packageinstaller/role/ui/RoleListLiveData.java +++ b/src/com/android/packageinstaller/role/ui/RoleListLiveData.java @@ -20,6 +20,7 @@ import android.app.role.OnRoleHoldersChangedListener; import android.app.role.RoleManager; import android.content.Context; import android.content.pm.ApplicationInfo; +import android.os.Process; import android.os.UserHandle; import android.util.ArrayMap; import android.util.Log; @@ -44,14 +45,10 @@ public class RoleListLiveData extends AsyncTaskLiveData> private static final String LOG_TAG = RoleListLiveData.class.getSimpleName(); private final boolean mExclusive; - @NonNull - private final UserHandle mUser; - @NonNull private final Context mContext; - public RoleListLiveData(boolean exclusive, @NonNull UserHandle user, @NonNull Context context) { + public RoleListLiveData(boolean exclusive, @NonNull Context context) { mExclusive = exclusive; - mUser = user; mContext = context; } @@ -60,14 +57,16 @@ public class RoleListLiveData extends AsyncTaskLiveData> loadValue(); RoleManager roleManager = mContext.getSystemService(RoleManager.class); + // TODO: STOPSHIP: Handle work profile? roleManager.addOnRoleHoldersChangedListenerAsUser(mContext.getMainExecutor(), this, - mUser); + Process.myUserHandle()); } @Override protected void onInactive() { RoleManager roleManager = mContext.getSystemService(RoleManager.class); - roleManager.removeOnRoleHoldersChangedListenerAsUser(this, mUser); + // TODO: STOPSHIP: Handle work profile? + roleManager.removeOnRoleHoldersChangedListenerAsUser(this, Process.myUserHandle()); } @Override @@ -75,7 +74,6 @@ public class RoleListLiveData extends AsyncTaskLiveData> loadValue(); } - @NonNull @Override @WorkerThread protected List loadValueInBackground() { @@ -91,23 +89,22 @@ public class RoleListLiveData extends AsyncTaskLiveData> continue; } - if (role.getQualifyingPackagesAsUser(mUser, mContext).isEmpty()) { + if (role.getQualifyingPackages(mContext).isEmpty()) { continue; } List holderApplicationInfos = new ArrayList<>(); - List holderPackageNames = roleManager.getRoleHoldersAsUser(role.getName(), - mUser); + List holderPackageNames = roleManager.getRoleHolders(role.getName()); int holderPackageNamesSize = holderPackageNames.size(); for (int holderPackageNamesIndex = 0; holderPackageNamesIndex < holderPackageNamesSize; holderPackageNamesIndex++) { String holderPackageName = holderPackageNames.get(holderPackageNamesIndex); - ApplicationInfo holderApplicationInfo = PackageUtils.getApplicationInfoAsUser( - holderPackageName, mUser, mContext); + ApplicationInfo holderApplicationInfo = PackageUtils.getApplicationInfo( + holderPackageName, mContext); if (holderApplicationInfo == null) { - Log.w(LOG_TAG, "Cannot get ApplicationInfo for application, package name: " - + holderPackageName + ", user id: " + mUser.getIdentifier()); + Log.w(LOG_TAG, "Cannot get ApplicationInfo for application, skipping: " + + holderPackageName); continue; } holderApplicationInfos.add(holderApplicationInfo); diff --git a/src/com/android/packageinstaller/role/ui/RoleListViewModel.java b/src/com/android/packageinstaller/role/ui/RoleListViewModel.java index 4d756dc9d..de29928de 100644 --- a/src/com/android/packageinstaller/role/ui/RoleListViewModel.java +++ b/src/com/android/packageinstaller/role/ui/RoleListViewModel.java @@ -17,92 +17,29 @@ package com.android.packageinstaller.role.ui; import android.app.Application; -import android.content.Context; -import android.os.Process; -import android.os.UserHandle; -import android.os.UserManager; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import androidx.lifecycle.AndroidViewModel; import androidx.lifecycle.ViewModel; import androidx.lifecycle.ViewModelProvider; -import java.util.List; -import java.util.Objects; - /** * {@link ViewModel} for a list of roles. */ public class RoleListViewModel extends AndroidViewModel { @NonNull - private final UserHandle mUser; - @NonNull - private final RoleListLiveData mUserLiveData; - @Nullable - private final UserHandle mWorkProfile; - @Nullable - private final RoleListLiveData mWorkLiveData; + private final RoleListLiveData mLiveData; public RoleListViewModel(boolean exclusive, @NonNull Application application) { super(application); - mUser = Process.myUserHandle(); - mUserLiveData = new RoleListLiveData(exclusive, mUser, application); - mWorkProfile = getWorkProfile(application); - mWorkLiveData = mWorkProfile != null ? new RoleListLiveData(exclusive, mWorkProfile, - application) : null; - } - - @Nullable - private static UserHandle getWorkProfile(@NonNull Context context) { - UserManager userManager = context.getSystemService(UserManager.class); - List profiles = userManager.getUserProfiles(); - UserHandle user = Process.myUserHandle(); - - int profilesSize = profiles.size(); - for (int i = 0; i < profilesSize; i++) { - UserHandle profile = profiles.get(i); - - if (Objects.equals(profile, user)) { - continue; - } - if (!userManager.isManagedProfile(profile.getIdentifier())) { - continue; - } - return profile; - } - return null; - } - - @NonNull - public UserHandle getUser() { - return mUser; + mLiveData = new RoleListLiveData(exclusive, application); } @NonNull public RoleListLiveData getLiveData() { - return mUserLiveData; - } - - /** - * Check whether the user has a work profile. - * - * @return whether the user has a work profile. - */ - public boolean hasWorkProfile() { - return mWorkProfile != null; - } - - @Nullable - public UserHandle getWorkProfile() { - return mWorkProfile; - } - - @Nullable - public RoleListLiveData getWorkLiveData() { - return mWorkLiveData; + return mLiveData; } /** diff --git a/src/com/android/packageinstaller/role/ui/RoleLiveData.java b/src/com/android/packageinstaller/role/ui/RoleLiveData.java index 55c3ccbc1..2b1117df5 100644 --- a/src/com/android/packageinstaller/role/ui/RoleLiveData.java +++ b/src/com/android/packageinstaller/role/ui/RoleLiveData.java @@ -20,6 +20,7 @@ import android.app.role.OnRoleHoldersChangedListener; import android.app.role.RoleManager; import android.content.Context; import android.content.pm.ApplicationInfo; +import android.os.Process; import android.os.UserHandle; import android.util.Log; @@ -41,16 +42,11 @@ public class RoleLiveData extends AsyncTaskLiveData private static final String LOG_TAG = RoleLiveData.class.getSimpleName(); - @NonNull private final Role mRole; - @NonNull - private final UserHandle mUser; - @NonNull private final Context mContext; - public RoleLiveData(@NonNull Role role, @NonNull UserHandle user, @NonNull Context context) { + public RoleLiveData(@NonNull Role role, @NonNull Context context) { mRole = role; - mUser = user; mContext = context; } @@ -59,13 +55,16 @@ public class RoleLiveData extends AsyncTaskLiveData loadValue(); RoleManager roleManager = mContext.getSystemService(RoleManager.class); - roleManager.addOnRoleHoldersChangedListenerAsUser(mContext.getMainExecutor(), this, mUser); + // TODO: STOPSHIP: Handle work profile? + roleManager.addOnRoleHoldersChangedListenerAsUser(mContext.getMainExecutor(), this, + Process.myUserHandle()); } @Override protected void onInactive() { RoleManager roleManager = mContext.getSystemService(RoleManager.class); - roleManager.removeOnRoleHoldersChangedListenerAsUser(this, mUser); + // TODO: STOPSHIP: Handle work profile? + roleManager.removeOnRoleHoldersChangedListenerAsUser(this, Process.myUserHandle()); } @Override @@ -76,14 +75,14 @@ public class RoleLiveData extends AsyncTaskLiveData @Override @WorkerThread protected RoleInfo loadValueInBackground() { - List qualifyingPackageNames = mRole.getQualifyingPackagesAsUser(mUser, mContext); + List qualifyingPackageNames = mRole.getQualifyingPackages(mContext); List qualifyingApplicationInfos = new ArrayList<>(); int qualifyingPackageNamesSize = qualifyingPackageNames.size(); for (int i = 0; i < qualifyingPackageNamesSize; i++) { String qualifyingPackageName = qualifyingPackageNames.get(i); - ApplicationInfo qualifyingApplicationInfo = PackageUtils.getApplicationInfoAsUser( - qualifyingPackageName, mUser, mContext); + ApplicationInfo qualifyingApplicationInfo = PackageUtils.getApplicationInfo( + qualifyingPackageName, mContext); if (qualifyingApplicationInfo == null) { Log.w(LOG_TAG, "Cannot get ApplicationInfo for application, skipping: " + qualifyingPackageName); @@ -93,7 +92,7 @@ public class RoleLiveData extends AsyncTaskLiveData } RoleManager roleManager = mContext.getSystemService(RoleManager.class); - List holderPackageNames = roleManager.getRoleHoldersAsUser(mRole.getName(), mUser); + List holderPackageNames = roleManager.getRoleHolders(mRole.getName()); return new RoleInfo(qualifyingApplicationInfos, holderPackageNames); } diff --git a/src/com/android/packageinstaller/role/utils/PackageUtils.java b/src/com/android/packageinstaller/role/utils/PackageUtils.java index 912355ec8..d3fe999e7 100644 --- a/src/com/android/packageinstaller/role/utils/PackageUtils.java +++ b/src/com/android/packageinstaller/role/utils/PackageUtils.java @@ -20,7 +20,6 @@ import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; -import android.os.UserHandle; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -74,26 +73,4 @@ public final class PackageUtils { return null; } } - - /** - * Retrieve the {@link ApplicationInfo} of an application. - * - * @param packageName the package name of the application - * @param user the user of the application - * @param context the {@code Context} to retrieve system services - * - * @return the {@link ApplicationInfo} of the application, or {@code null} if not found - */ - @Nullable - public static ApplicationInfo getApplicationInfoAsUser(@NonNull String packageName, - @NonNull UserHandle user, @NonNull Context context) { - PackageManager packageManager = context.getPackageManager(); - try { - return packageManager.getApplicationInfoAsUser(packageName, - PackageManager.MATCH_DIRECT_BOOT_AWARE - | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, user); - } catch (PackageManager.NameNotFoundException e) { - return null; - } - } } -- GitLab From 494b8d48f55be4618e68fd9535eb902a38075d06 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Wed, 12 Dec 2018 09:04:03 -0800 Subject: [PATCH 208/701] Tweak strings. Change-Id: Ic4476ef1b474d4318ada16fc1b3d9c507852e932 Fixes: 120871985 Test: Visibly inspect modified strings. --- res/values/strings.xml | 9 ++++++--- .../ui/handheld/PermissionControlPreference.java | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 9474e1a15..3ab5f9a4a 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -170,7 +170,7 @@ Always - + Only while using app @@ -240,8 +240,8 @@ Permissions usage - - %1$s - %2$s ago + + %1$s - Last access %2$s ago Any permission @@ -395,6 +395,9 @@ The app developer did not specify how the app uses your data. + + Only while app is in use + No permissions allowed diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionControlPreference.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionControlPreference.java index e0d8891f8..34116173b 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionControlPreference.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionControlPreference.java @@ -101,7 +101,7 @@ public class PermissionControlPreference extends Preference { if (group.hasPermissionWithBackgroundMode() && group.areRuntimePermissionsGranted()) { AppPermissionGroup backgroundGroup = group.getBackgroundPermissions(); if (backgroundGroup == null || !backgroundGroup.areRuntimePermissionsGranted()) { - setSummary(R.string.permission_access_only_foreground); + setSummary(R.string.permission_subtitle_only_in_foreground); return; } } -- GitLab From 659759bf4bbaa61f85476c278176c019e04a41f8 Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Mon, 17 Dec 2018 20:06:55 +0000 Subject: [PATCH 209/701] Revert "Revert "Add work profile support for the new Default apps UI."" This reverts commit 1da06cd0b762033234d1f5966b0672de327650d2. Reason for revert: The change itself doesn't break any build other than mainline_modules-userdebug, and that build breakage is likely caused by building this change against an old SDK which didn't have the new APIs. Once we make sure we are building with a new SDK we can merge this double-revert. Change-Id: I07c7231ec9fb0f0c2eb56b590a513e16ba048916 --- res/values/strings.xml | 3 + .../role/model/PreferredActivity.java | 4 +- .../role/model/RequiredActivity.java | 7 +- .../role/model/RequiredBroadcastReceiver.java | 7 +- .../role/model/RequiredComponent.java | 27 ++++--- .../role/model/RequiredContentProvider.java | 7 +- .../role/model/RequiredService.java | 7 +- .../packageinstaller/role/model/Role.java | 11 ++- .../role/ui/AddRoleHolderStateLiveData.java | 7 +- .../role/ui/DefaultAppActivity.java | 15 +++- .../role/ui/DefaultAppFragment.java | 19 +++-- .../role/ui/DefaultAppListFragment.java | 80 +++++++++++++++---- .../role/ui/DefaultAppViewModel.java | 15 +++- .../role/ui/RequestRoleFragment.java | 4 +- .../role/ui/RoleListLiveData.java | 27 ++++--- .../role/ui/RoleListViewModel.java | 69 +++++++++++++++- .../role/ui/RoleLiveData.java | 23 +++--- .../role/utils/PackageUtils.java | 23 ++++++ 18 files changed, 269 insertions(+), 86 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index c83eaab4b..e4ec6296e 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -429,6 +429,9 @@ No default apps + + Default for work + None diff --git a/src/com/android/packageinstaller/role/model/PreferredActivity.java b/src/com/android/packageinstaller/role/model/PreferredActivity.java index ad96e45b2..75553d5b4 100644 --- a/src/com/android/packageinstaller/role/model/PreferredActivity.java +++ b/src/com/android/packageinstaller/role/model/PreferredActivity.java @@ -20,6 +20,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.IntentFilter; import android.content.pm.PackageManager; +import android.os.Process; import androidx.annotation.NonNull; @@ -68,7 +69,8 @@ public class PreferredActivity { */ public void configure(@NonNull String packageName, @NonNull Context context) { IntentFilter intentFilter = mActivity.getIntentFilterData().createIntentFilter(); - List activities = mActivity.getQualifyingComponents(context); + List activities = mActivity.getQualifyingComponentsAsUser( + Process.myUserHandle(), context); ComponentName packageActivity = mActivity.getQualifyingComponentForPackage( packageName, context); // TODO: STOPSHIP: Race condition, what if packageActivity became null? Just don't crash? diff --git a/src/com/android/packageinstaller/role/model/RequiredActivity.java b/src/com/android/packageinstaller/role/model/RequiredActivity.java index b39bbd1d5..742e7be97 100644 --- a/src/com/android/packageinstaller/role/model/RequiredActivity.java +++ b/src/com/android/packageinstaller/role/model/RequiredActivity.java @@ -22,6 +22,7 @@ import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.Bundle; +import android.os.UserHandle; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -40,10 +41,10 @@ public class RequiredActivity extends RequiredComponent { @NonNull @Override - protected List queryIntentComponents(@NonNull Intent intent, int flags, - @NonNull Context context) { + protected List queryIntentComponentsAsUser(@NonNull Intent intent, int flags, + @NonNull UserHandle user, @NonNull Context context) { PackageManager packageManager = context.getPackageManager(); - return packageManager.queryIntentActivities(intent, flags); + return packageManager.queryIntentActivitiesAsUser(intent, flags, user); } @NonNull diff --git a/src/com/android/packageinstaller/role/model/RequiredBroadcastReceiver.java b/src/com/android/packageinstaller/role/model/RequiredBroadcastReceiver.java index 21eb670af..37a8f1ca1 100644 --- a/src/com/android/packageinstaller/role/model/RequiredBroadcastReceiver.java +++ b/src/com/android/packageinstaller/role/model/RequiredBroadcastReceiver.java @@ -22,6 +22,7 @@ import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.Bundle; +import android.os.UserHandle; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -40,10 +41,10 @@ public class RequiredBroadcastReceiver extends RequiredComponent { @NonNull @Override - protected List queryIntentComponents(@NonNull Intent intent, int flags, - @NonNull Context context) { + protected List queryIntentComponentsAsUser(@NonNull Intent intent, int flags, + @NonNull UserHandle user, @NonNull Context context) { PackageManager packageManager = context.getPackageManager(); - return packageManager.queryBroadcastReceivers(intent, flags); + return packageManager.queryBroadcastReceiversAsUser(intent, flags, user); } @NonNull diff --git a/src/com/android/packageinstaller/role/model/RequiredComponent.java b/src/com/android/packageinstaller/role/model/RequiredComponent.java index e810af696..951d2a02c 100644 --- a/src/com/android/packageinstaller/role/model/RequiredComponent.java +++ b/src/com/android/packageinstaller/role/model/RequiredComponent.java @@ -22,6 +22,8 @@ import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.Bundle; +import android.os.Process; +import android.os.UserHandle; import android.util.ArraySet; import android.util.Log; @@ -96,8 +98,8 @@ public abstract class RequiredComponent { @Nullable public ComponentName getQualifyingComponentForPackage(@NonNull String packageName, @NonNull Context context) { - List componentNames = getQualifyingComponents(packageName, - context); + List componentNames = getQualifyingComponentsInternal(packageName, + Process.myUserHandle(), context); return !componentNames.isEmpty() ? componentNames.get(0) : null; } @@ -105,20 +107,22 @@ public abstract class RequiredComponent { * Get the list of components that match this required component, at most one component per * package and ordered from best to worst. * + * @param user the user to get the qualifying components. * @param context the {@code Context} to retrieve system services * * @return the list of matching components * - * @see Role#getQualifyingPackages(Context) + * @see Role#getQualifyingPackagesAsUser(UserHandle, Context) */ @NonNull - public List getQualifyingComponents(@NonNull Context context) { - return getQualifyingComponents(null, context); + public List getQualifyingComponentsAsUser(@NonNull UserHandle user, + @NonNull Context context) { + return getQualifyingComponentsInternal(null, user, context); } @NonNull - private List getQualifyingComponents(@Nullable String packageName, - @NonNull Context context) { + private List getQualifyingComponentsInternal(@Nullable String packageName, + @NonNull UserHandle user, @NonNull Context context) { Intent intent = mIntentFilterData.createIntent(); if (packageName != null) { intent.setPackage(packageName); @@ -129,7 +133,7 @@ public abstract class RequiredComponent { if (hasMetaData) { flags |= PackageManager.GET_META_DATA; } - List resolveInfos = queryIntentComponents(intent, flags, context); + List resolveInfos = queryIntentComponentsAsUser(intent, flags, user, context); ArraySet componentPackageNames = new ArraySet<>(); List componentNames = new ArrayList<>(); @@ -182,14 +186,15 @@ public abstract class RequiredComponent { * to worst. * * @param intent the {@code Intent} to match against - * @param flags the flags to be used for this query + * @param flags the flags for this query + * @param user the user for this query * @param context the {@code Context} to retrieve system services * * @return the list of matching components */ @NonNull - protected abstract List queryIntentComponents(@NonNull Intent intent, int flags, - @NonNull Context context); + protected abstract List queryIntentComponentsAsUser(@NonNull Intent intent, + int flags, @NonNull UserHandle user, @NonNull Context context); /** * Get the {@code ComponentName} of a component. diff --git a/src/com/android/packageinstaller/role/model/RequiredContentProvider.java b/src/com/android/packageinstaller/role/model/RequiredContentProvider.java index eb0f5f079..776c83997 100644 --- a/src/com/android/packageinstaller/role/model/RequiredContentProvider.java +++ b/src/com/android/packageinstaller/role/model/RequiredContentProvider.java @@ -22,6 +22,7 @@ import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.Bundle; +import android.os.UserHandle; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -40,10 +41,10 @@ public class RequiredContentProvider extends RequiredComponent { @NonNull @Override - protected List queryIntentComponents(@NonNull Intent intent, int flags, - @NonNull Context context) { + protected List queryIntentComponentsAsUser(@NonNull Intent intent, int flags, + @NonNull UserHandle user, @NonNull Context context) { PackageManager packageManager = context.getPackageManager(); - return packageManager.queryIntentContentProviders(intent, flags); + return packageManager.queryIntentContentProvidersAsUser(intent, flags, user); } @NonNull diff --git a/src/com/android/packageinstaller/role/model/RequiredService.java b/src/com/android/packageinstaller/role/model/RequiredService.java index 9bab7b9f7..17fc5f079 100644 --- a/src/com/android/packageinstaller/role/model/RequiredService.java +++ b/src/com/android/packageinstaller/role/model/RequiredService.java @@ -22,6 +22,7 @@ import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.Bundle; +import android.os.UserHandle; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -40,10 +41,10 @@ public class RequiredService extends RequiredComponent { @NonNull @Override - protected List queryIntentComponents(@NonNull Intent intent, int flags, - @NonNull Context context) { + protected List queryIntentComponentsAsUser(@NonNull Intent intent, int flags, + @NonNull UserHandle user, @NonNull Context context) { PackageManager packageManager = context.getPackageManager(); - return packageManager.queryIntentServices(intent, flags); + return packageManager.queryIntentServicesAsUser(intent, flags, user); } @NonNull diff --git a/src/com/android/packageinstaller/role/model/Role.java b/src/com/android/packageinstaller/role/model/Role.java index d095c64fa..2ea8d4628 100644 --- a/src/com/android/packageinstaller/role/model/Role.java +++ b/src/com/android/packageinstaller/role/model/Role.java @@ -21,6 +21,7 @@ import android.app.role.RoleManager; import android.content.ComponentName; import android.content.Context; import android.content.pm.ApplicationInfo; +import android.os.UserHandle; import android.util.ArrayMap; import android.util.Log; @@ -168,15 +169,17 @@ public class Role { } /** - * Get the set of packages that are qualified for this role, i.e. packages containing all the + * Get the list of packages that are qualified for this role, i.e. packages containing all the * required components. * + * @param user the user to get the qualifying packages. * @param context the {@code Context} to retrieve system services * * @return the set of packages that are qualified for this role */ @NonNull - public List getQualifyingPackages(@NonNull Context context) { + public List getQualifyingPackagesAsUser(@NonNull UserHandle user, + @NonNull Context context) { ArrayMap packageComponentCountMap = new ArrayMap<>(); int requiredComponentsSize = mRequiredComponents.size(); for (int requiredComponentsIndex = 0; requiredComponentsIndex < requiredComponentsSize; @@ -184,8 +187,8 @@ public class Role { RequiredComponent requiredComponent = mRequiredComponents.get(requiredComponentsIndex); // This returns at most one component per package. - List qualifyingComponents = requiredComponent.getQualifyingComponents( - context); + List qualifyingComponents = + requiredComponent.getQualifyingComponentsAsUser(user, context); int qualifyingComponentsSize = qualifyingComponents.size(); for (int qualifyingComponentsIndex = 0; qualifyingComponentsIndex < qualifyingComponentsSize; diff --git a/src/com/android/packageinstaller/role/ui/AddRoleHolderStateLiveData.java b/src/com/android/packageinstaller/role/ui/AddRoleHolderStateLiveData.java index 45c0e8061..9606c6db4 100644 --- a/src/com/android/packageinstaller/role/ui/AddRoleHolderStateLiveData.java +++ b/src/com/android/packageinstaller/role/ui/AddRoleHolderStateLiveData.java @@ -19,7 +19,6 @@ package com.android.packageinstaller.role.ui; import android.app.role.RoleManager; import android.app.role.RoleManagerCallback; import android.content.Context; -import android.os.Process; import android.os.UserHandle; import android.util.Log; @@ -50,10 +49,11 @@ public class AddRoleHolderStateLiveData extends LiveData { * * @param roleName the name of the role * @param packageName the package name of the application + * @param user the user to add the role holder for * @param context the {@code Context} to retrieve system services */ - public void addRoleHolder(@NonNull String roleName, @NonNull String packageName, - @NonNull Context context) { + public void addRoleHolderAsUser(@NonNull String roleName, @NonNull String packageName, + @NonNull UserHandle user, @NonNull Context context) { if (getValue() != STATE_IDLE) { Log.e(LOG_TAG, "Already (tried) adding package as role holder, requested role: " + roleName + ", requested package: " + packageName); @@ -64,7 +64,6 @@ public class AddRoleHolderStateLiveData extends LiveData { setValue(STATE_ADDING); RoleManager roleManager = context.getSystemService(RoleManager.class); - UserHandle user = Process.myUserHandle(); Executor executor = context.getMainExecutor(); roleManager.addRoleHolderAsUser(roleName, packageName, user, executor, new RoleManagerCallback() { diff --git a/src/com/android/packageinstaller/role/ui/DefaultAppActivity.java b/src/com/android/packageinstaller/role/ui/DefaultAppActivity.java index b1ae2c0a2..67b2dc9b8 100644 --- a/src/com/android/packageinstaller/role/ui/DefaultAppActivity.java +++ b/src/com/android/packageinstaller/role/ui/DefaultAppActivity.java @@ -19,6 +19,7 @@ package com.android.packageinstaller.role.ui; import android.content.Context; import android.content.Intent; import android.os.Bundle; +import android.os.UserHandle; import android.util.Log; import androidx.annotation.NonNull; @@ -39,21 +40,27 @@ public class DefaultAppActivity extends FragmentActivity { * Create an intent for starting this activity. * * @param roleName the name of the role for the default app + * @param user the user for the default app * @param context the context to create the intent * * @return an intent to start this activity */ @NonNull - public static Intent createIntent(@NonNull String roleName, @NonNull Context context) { + public static Intent createIntent(@NonNull String roleName, @NonNull UserHandle user, + @NonNull Context context) { return new Intent(context, DefaultAppActivity.class) - .putExtra(DefaultAppFragment.EXTRA_ROLE_NAME, roleName); + .putExtra(DefaultAppFragment.EXTRA_ROLE_NAME, roleName) + .putExtra(Intent.EXTRA_USER, user); } @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - String roleName = getIntent().getStringExtra(DefaultAppFragment.EXTRA_ROLE_NAME); + Intent intent = getIntent(); + String roleName = intent.getStringExtra(DefaultAppFragment.EXTRA_ROLE_NAME); + UserHandle user = intent.getParcelableExtra(Intent.EXTRA_USER); + Role role = Roles.getRoles(this).get(roleName); if (role == null) { Log.e(LOG_TAG, "Unknown role: " + roleName); @@ -62,7 +69,7 @@ public class DefaultAppActivity extends FragmentActivity { } if (savedInstanceState == null) { - DefaultAppFragment fragment = DefaultAppFragment.newInstance(roleName); + DefaultAppFragment fragment = DefaultAppFragment.newInstance(roleName, user); getSupportFragmentManager().beginTransaction() .add(android.R.id.content, fragment) .commit(); diff --git a/src/com/android/packageinstaller/role/ui/DefaultAppFragment.java b/src/com/android/packageinstaller/role/ui/DefaultAppFragment.java index a3497bc19..efa588787 100644 --- a/src/com/android/packageinstaller/role/ui/DefaultAppFragment.java +++ b/src/com/android/packageinstaller/role/ui/DefaultAppFragment.java @@ -18,6 +18,7 @@ package com.android.packageinstaller.role.ui; import android.app.Activity; import android.content.Context; +import android.content.Intent; import android.content.pm.ApplicationInfo; import android.os.Bundle; import android.os.UserHandle; @@ -54,6 +55,8 @@ public class DefaultAppFragment extends SettingsFragment private String mRoleName; + private UserHandle mUser; + private Role mRole; private DefaultAppViewModel mViewModel; @@ -61,15 +64,18 @@ public class DefaultAppFragment extends SettingsFragment /** * Create a new instance of this fragment. * - * @param roleName the name of the role to be managed + * @param roleName the name of the role for the default app + * @param user the user for the default app * * @return a new instance of this fragment */ @NonNull - public static DefaultAppFragment newInstance(@NonNull String roleName) { + public static DefaultAppFragment newInstance(@NonNull String roleName, + @NonNull UserHandle user) { DefaultAppFragment fragment = new DefaultAppFragment(); Bundle arguments = new Bundle(); arguments.putString(EXTRA_ROLE_NAME, roleName); + arguments.putParcelable(Intent.EXTRA_USER, user); fragment.setArguments(arguments); return fragment; } @@ -78,7 +84,9 @@ public class DefaultAppFragment extends SettingsFragment public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - mRoleName = getArguments().getString(EXTRA_ROLE_NAME); + Bundle arguments = getArguments(); + mRoleName = arguments.getString(EXTRA_ROLE_NAME); + mUser = arguments.getParcelable(Intent.EXTRA_USER); } @Override @@ -89,7 +97,7 @@ public class DefaultAppFragment extends SettingsFragment mRole = Roles.getRoles(activity).get(mRoleName); activity.setTitle(mRole.getLabelResource()); - mViewModel = ViewModelProviders.of(this, new DefaultAppViewModel.Factory(mRole, + mViewModel = ViewModelProviders.of(this, new DefaultAppViewModel.Factory(mRole, mUser, activity.getApplication())).get(DefaultAppViewModel.class); mViewModel.getRoleLiveData().observe(this, this::onRoleInfoChanged); mViewModel.getAddRoleHolderStateLiveData().observe(this, this::onAddRoleHolderStateChanged); @@ -173,7 +181,8 @@ public class DefaultAppFragment extends SettingsFragment } String packageName = preference.getKey(); - addRoleHolderStateLiveData.addRoleHolder(mRoleName, packageName, requireContext()); + addRoleHolderStateLiveData.addRoleHolderAsUser(mRoleName, packageName, mUser, + requireContext()); return true; } } diff --git a/src/com/android/packageinstaller/role/ui/DefaultAppListFragment.java b/src/com/android/packageinstaller/role/ui/DefaultAppListFragment.java index ef82dd2ea..64a726737 100644 --- a/src/com/android/packageinstaller/role/ui/DefaultAppListFragment.java +++ b/src/com/android/packageinstaller/role/ui/DefaultAppListFragment.java @@ -28,6 +28,8 @@ import androidx.annotation.Nullable; import androidx.annotation.StringRes; import androidx.lifecycle.ViewModelProviders; import androidx.preference.Preference; +import androidx.preference.PreferenceCategory; +import androidx.preference.PreferenceGroup; import androidx.preference.PreferenceManager; import androidx.preference.PreferenceScreen; @@ -46,6 +48,8 @@ public class DefaultAppListFragment extends SettingsFragment private static final String LOG_TAG = DefaultAppListFragment.class.getSimpleName(); + private static final String PREFERENCE_KEY_WORK_CATEGORY = "work_category"; + private RoleListViewModel mViewModel; /** @@ -64,7 +68,10 @@ public class DefaultAppListFragment extends SettingsFragment mViewModel = ViewModelProviders.of(this, new RoleListViewModel.Factory(true, requireActivity().getApplication())).get(RoleListViewModel.class); - mViewModel.getLiveData().observe(this, this::onRoleListChanged); + mViewModel.getLiveData().observe(this, roleItems -> onRoleListChanged()); + if (mViewModel.hasWorkProfile()) { + mViewModel.getWorkLiveData().observe(this, roleItems -> onRoleListChanged()); + } } @Override @@ -78,27 +85,72 @@ public class DefaultAppListFragment extends SettingsFragment return R.string.help_uri_default_apps; } - private void onRoleListChanged(@NonNull List roleItems) { + private void onRoleListChanged() { + List roleItems = mViewModel.getLiveData().getValue(); + if (roleItems == null) { + return; + } + boolean hasWorkProfile = mViewModel.hasWorkProfile(); + List workRoleItems = null; + if (hasWorkProfile) { + workRoleItems = mViewModel.getWorkLiveData().getValue(); + if (workRoleItems == null) { + return; + } + } + PreferenceManager preferenceManager = getPreferenceManager(); Context context = preferenceManager.getContext(); - PreferenceScreen preferenceScreen = getPreferenceScreen(); ArrayMap oldPreferences = new ArrayMap<>(); + PreferenceCategory oldWorkPreferenceCategory = null; + ArrayMap oldWorkPreferences = new ArrayMap<>(); if (preferenceScreen == null) { preferenceScreen = preferenceManager.createPreferenceScreen(context); setPreferenceScreen(preferenceScreen); } else { - for (int i = preferenceScreen.getPreferenceCount() - 1; i >= 0; --i) { - Preference preference = preferenceScreen.getPreference(i); + oldWorkPreferenceCategory = (PreferenceCategory) preferenceScreen.findPreference( + PREFERENCE_KEY_WORK_CATEGORY); + if (oldWorkPreferenceCategory != null) { + clearPreferences(oldWorkPreferenceCategory, oldWorkPreferences); + preferenceScreen.removePreference(oldWorkPreferenceCategory); + } + clearPreferences(preferenceScreen, oldPreferences); + } - preferenceScreen.removePreference(preference); - oldPreferences.put(preference.getKey(), preference); + addPreferences(preferenceScreen, roleItems, oldPreferences, this, mViewModel.getUser(), + context); + if (hasWorkProfile) { + PreferenceCategory workPreferenceCategory = oldWorkPreferenceCategory; + if (workPreferenceCategory == null) { + workPreferenceCategory = new PreferenceCategory(context); + workPreferenceCategory.setKey(PREFERENCE_KEY_WORK_CATEGORY); + workPreferenceCategory.setTitle(R.string.default_apps_for_work); } + preferenceScreen.addPreference(workPreferenceCategory); + addPreferences(workPreferenceCategory, workRoleItems, oldWorkPreferences, this, + mViewModel.getWorkProfile(), context); } + updateState(); + } + + private static void clearPreferences(@NonNull PreferenceGroup preferenceGroup, + @NonNull ArrayMap oldPreferences) { + for (int i = preferenceGroup.getPreferenceCount() - 1; i >= 0; --i) { + Preference Preference = preferenceGroup.getPreference(i); + + oldPreferences.put(Preference.getKey(), Preference); + } + } + + private static void addPreferences(@NonNull PreferenceGroup preferenceGroup, + @NonNull List roleItems, @NonNull ArrayMap oldPreferences, + @NonNull Preference.OnPreferenceClickListener listener, @NonNull UserHandle user, + @NonNull Context context) { int roleItemsSize = roleItems.size(); - for (int roleItemsIndex = 0; roleItemsIndex < roleItemsSize; roleItemsIndex++) { - RoleItem roleItem = roleItems.get(roleItemsIndex); + for (int i = 0; i < roleItemsSize; i++) { + RoleItem roleItem = roleItems.get(i); Role role = roleItem.getRole(); Preference preference = oldPreferences.get(role.getName()); @@ -108,7 +160,8 @@ public class DefaultAppListFragment extends SettingsFragment preference.setIconSpaceReserved(true); preference.setTitle(role.getLabelResource()); preference.setPersistent(false); - preference.setOnPreferenceClickListener(this); + preference.setOnPreferenceClickListener(listener); + preference.getExtras().putParcelable(Intent.EXTRA_USER, user); } List holderApplicationInfos = roleItem.getHolderApplicationInfos(); @@ -123,16 +176,15 @@ public class DefaultAppListFragment extends SettingsFragment } // TODO: Ordering? - preferenceScreen.addPreference(preference); + preferenceGroup.addPreference(preference); } - - updateState(); } @Override public boolean onPreferenceClick(@NonNull Preference preference) { String roleName = preference.getKey(); - Intent intent = DefaultAppActivity.createIntent(roleName, requireContext()); + UserHandle user = preference.getExtras().getParcelable(Intent.EXTRA_USER); + Intent intent = DefaultAppActivity.createIntent(roleName, user, requireContext()); startActivity(intent); return true; } diff --git a/src/com/android/packageinstaller/role/ui/DefaultAppViewModel.java b/src/com/android/packageinstaller/role/ui/DefaultAppViewModel.java index 163327aa7..b51191a82 100644 --- a/src/com/android/packageinstaller/role/ui/DefaultAppViewModel.java +++ b/src/com/android/packageinstaller/role/ui/DefaultAppViewModel.java @@ -17,6 +17,7 @@ package com.android.packageinstaller.role.ui; import android.app.Application; +import android.os.UserHandle; import androidx.annotation.NonNull; import androidx.lifecycle.AndroidViewModel; @@ -37,10 +38,11 @@ public class DefaultAppViewModel extends AndroidViewModel { private final AddRoleHolderStateLiveData mAddRoleHolderStateLiveData = new AddRoleHolderStateLiveData(); - public DefaultAppViewModel(@NonNull Role role, @NonNull Application application) { + public DefaultAppViewModel(@NonNull Role role, @NonNull UserHandle user, + @NonNull Application application) { super(application); - mRoleLiveData = new RoleLiveData(role, application); + mRoleLiveData = new RoleLiveData(role, user, application); } @NonNull @@ -61,11 +63,16 @@ public class DefaultAppViewModel extends AndroidViewModel { @NonNull private Role mRole; + @NonNull + private UserHandle mUser; + @NonNull private Application mApplication; - public Factory(@NonNull Role role, @NonNull Application application) { + public Factory(@NonNull Role role, @NonNull UserHandle user, + @NonNull Application application) { mRole = role; + mUser = user; mApplication = application; } @@ -73,7 +80,7 @@ public class DefaultAppViewModel extends AndroidViewModel { @Override public T create(@NonNull Class modelClass) { //noinspection unchecked - return (T) new DefaultAppViewModel(mRole, mApplication); + return (T) new DefaultAppViewModel(mRole, mUser, mApplication); } } } diff --git a/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java b/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java index c9ed25090..fd185e6cf 100644 --- a/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java +++ b/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java @@ -25,6 +25,7 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.os.Bundle; +import android.os.Process; import android.text.Html; import android.util.Log; @@ -205,7 +206,8 @@ public class RequestRoleFragment extends DialogFragment { } private void addRoleHolder() { - mViewModel.getLiveData().addRoleHolder(mRoleName, mPackageName, requireContext()); + mViewModel.getLiveData().addRoleHolderAsUser(mRoleName, mPackageName, + Process.myUserHandle(), requireContext()); } private void setResultOkAndFinish() { diff --git a/src/com/android/packageinstaller/role/ui/RoleListLiveData.java b/src/com/android/packageinstaller/role/ui/RoleListLiveData.java index f76fc9736..c4435a77d 100644 --- a/src/com/android/packageinstaller/role/ui/RoleListLiveData.java +++ b/src/com/android/packageinstaller/role/ui/RoleListLiveData.java @@ -20,7 +20,6 @@ import android.app.role.OnRoleHoldersChangedListener; import android.app.role.RoleManager; import android.content.Context; import android.content.pm.ApplicationInfo; -import android.os.Process; import android.os.UserHandle; import android.util.ArrayMap; import android.util.Log; @@ -45,10 +44,14 @@ public class RoleListLiveData extends AsyncTaskLiveData> private static final String LOG_TAG = RoleListLiveData.class.getSimpleName(); private final boolean mExclusive; + @NonNull + private final UserHandle mUser; + @NonNull private final Context mContext; - public RoleListLiveData(boolean exclusive, @NonNull Context context) { + public RoleListLiveData(boolean exclusive, @NonNull UserHandle user, @NonNull Context context) { mExclusive = exclusive; + mUser = user; mContext = context; } @@ -57,16 +60,14 @@ public class RoleListLiveData extends AsyncTaskLiveData> loadValue(); RoleManager roleManager = mContext.getSystemService(RoleManager.class); - // TODO: STOPSHIP: Handle work profile? roleManager.addOnRoleHoldersChangedListenerAsUser(mContext.getMainExecutor(), this, - Process.myUserHandle()); + mUser); } @Override protected void onInactive() { RoleManager roleManager = mContext.getSystemService(RoleManager.class); - // TODO: STOPSHIP: Handle work profile? - roleManager.removeOnRoleHoldersChangedListenerAsUser(this, Process.myUserHandle()); + roleManager.removeOnRoleHoldersChangedListenerAsUser(this, mUser); } @Override @@ -74,6 +75,7 @@ public class RoleListLiveData extends AsyncTaskLiveData> loadValue(); } + @NonNull @Override @WorkerThread protected List loadValueInBackground() { @@ -89,22 +91,23 @@ public class RoleListLiveData extends AsyncTaskLiveData> continue; } - if (role.getQualifyingPackages(mContext).isEmpty()) { + if (role.getQualifyingPackagesAsUser(mUser, mContext).isEmpty()) { continue; } List holderApplicationInfos = new ArrayList<>(); - List holderPackageNames = roleManager.getRoleHolders(role.getName()); + List holderPackageNames = roleManager.getRoleHoldersAsUser(role.getName(), + mUser); int holderPackageNamesSize = holderPackageNames.size(); for (int holderPackageNamesIndex = 0; holderPackageNamesIndex < holderPackageNamesSize; holderPackageNamesIndex++) { String holderPackageName = holderPackageNames.get(holderPackageNamesIndex); - ApplicationInfo holderApplicationInfo = PackageUtils.getApplicationInfo( - holderPackageName, mContext); + ApplicationInfo holderApplicationInfo = PackageUtils.getApplicationInfoAsUser( + holderPackageName, mUser, mContext); if (holderApplicationInfo == null) { - Log.w(LOG_TAG, "Cannot get ApplicationInfo for application, skipping: " - + holderPackageName); + Log.w(LOG_TAG, "Cannot get ApplicationInfo for application, package name: " + + holderPackageName + ", user id: " + mUser.getIdentifier()); continue; } holderApplicationInfos.add(holderApplicationInfo); diff --git a/src/com/android/packageinstaller/role/ui/RoleListViewModel.java b/src/com/android/packageinstaller/role/ui/RoleListViewModel.java index de29928de..4d756dc9d 100644 --- a/src/com/android/packageinstaller/role/ui/RoleListViewModel.java +++ b/src/com/android/packageinstaller/role/ui/RoleListViewModel.java @@ -17,29 +17,92 @@ package com.android.packageinstaller.role.ui; import android.app.Application; +import android.content.Context; +import android.os.Process; +import android.os.UserHandle; +import android.os.UserManager; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.lifecycle.AndroidViewModel; import androidx.lifecycle.ViewModel; import androidx.lifecycle.ViewModelProvider; +import java.util.List; +import java.util.Objects; + /** * {@link ViewModel} for a list of roles. */ public class RoleListViewModel extends AndroidViewModel { @NonNull - private final RoleListLiveData mLiveData; + private final UserHandle mUser; + @NonNull + private final RoleListLiveData mUserLiveData; + @Nullable + private final UserHandle mWorkProfile; + @Nullable + private final RoleListLiveData mWorkLiveData; public RoleListViewModel(boolean exclusive, @NonNull Application application) { super(application); - mLiveData = new RoleListLiveData(exclusive, application); + mUser = Process.myUserHandle(); + mUserLiveData = new RoleListLiveData(exclusive, mUser, application); + mWorkProfile = getWorkProfile(application); + mWorkLiveData = mWorkProfile != null ? new RoleListLiveData(exclusive, mWorkProfile, + application) : null; + } + + @Nullable + private static UserHandle getWorkProfile(@NonNull Context context) { + UserManager userManager = context.getSystemService(UserManager.class); + List profiles = userManager.getUserProfiles(); + UserHandle user = Process.myUserHandle(); + + int profilesSize = profiles.size(); + for (int i = 0; i < profilesSize; i++) { + UserHandle profile = profiles.get(i); + + if (Objects.equals(profile, user)) { + continue; + } + if (!userManager.isManagedProfile(profile.getIdentifier())) { + continue; + } + return profile; + } + return null; + } + + @NonNull + public UserHandle getUser() { + return mUser; } @NonNull public RoleListLiveData getLiveData() { - return mLiveData; + return mUserLiveData; + } + + /** + * Check whether the user has a work profile. + * + * @return whether the user has a work profile. + */ + public boolean hasWorkProfile() { + return mWorkProfile != null; + } + + @Nullable + public UserHandle getWorkProfile() { + return mWorkProfile; + } + + @Nullable + public RoleListLiveData getWorkLiveData() { + return mWorkLiveData; } /** diff --git a/src/com/android/packageinstaller/role/ui/RoleLiveData.java b/src/com/android/packageinstaller/role/ui/RoleLiveData.java index 2b1117df5..55c3ccbc1 100644 --- a/src/com/android/packageinstaller/role/ui/RoleLiveData.java +++ b/src/com/android/packageinstaller/role/ui/RoleLiveData.java @@ -20,7 +20,6 @@ import android.app.role.OnRoleHoldersChangedListener; import android.app.role.RoleManager; import android.content.Context; import android.content.pm.ApplicationInfo; -import android.os.Process; import android.os.UserHandle; import android.util.Log; @@ -42,11 +41,16 @@ public class RoleLiveData extends AsyncTaskLiveData private static final String LOG_TAG = RoleLiveData.class.getSimpleName(); + @NonNull private final Role mRole; + @NonNull + private final UserHandle mUser; + @NonNull private final Context mContext; - public RoleLiveData(@NonNull Role role, @NonNull Context context) { + public RoleLiveData(@NonNull Role role, @NonNull UserHandle user, @NonNull Context context) { mRole = role; + mUser = user; mContext = context; } @@ -55,16 +59,13 @@ public class RoleLiveData extends AsyncTaskLiveData loadValue(); RoleManager roleManager = mContext.getSystemService(RoleManager.class); - // TODO: STOPSHIP: Handle work profile? - roleManager.addOnRoleHoldersChangedListenerAsUser(mContext.getMainExecutor(), this, - Process.myUserHandle()); + roleManager.addOnRoleHoldersChangedListenerAsUser(mContext.getMainExecutor(), this, mUser); } @Override protected void onInactive() { RoleManager roleManager = mContext.getSystemService(RoleManager.class); - // TODO: STOPSHIP: Handle work profile? - roleManager.removeOnRoleHoldersChangedListenerAsUser(this, Process.myUserHandle()); + roleManager.removeOnRoleHoldersChangedListenerAsUser(this, mUser); } @Override @@ -75,14 +76,14 @@ public class RoleLiveData extends AsyncTaskLiveData @Override @WorkerThread protected RoleInfo loadValueInBackground() { - List qualifyingPackageNames = mRole.getQualifyingPackages(mContext); + List qualifyingPackageNames = mRole.getQualifyingPackagesAsUser(mUser, mContext); List qualifyingApplicationInfos = new ArrayList<>(); int qualifyingPackageNamesSize = qualifyingPackageNames.size(); for (int i = 0; i < qualifyingPackageNamesSize; i++) { String qualifyingPackageName = qualifyingPackageNames.get(i); - ApplicationInfo qualifyingApplicationInfo = PackageUtils.getApplicationInfo( - qualifyingPackageName, mContext); + ApplicationInfo qualifyingApplicationInfo = PackageUtils.getApplicationInfoAsUser( + qualifyingPackageName, mUser, mContext); if (qualifyingApplicationInfo == null) { Log.w(LOG_TAG, "Cannot get ApplicationInfo for application, skipping: " + qualifyingPackageName); @@ -92,7 +93,7 @@ public class RoleLiveData extends AsyncTaskLiveData } RoleManager roleManager = mContext.getSystemService(RoleManager.class); - List holderPackageNames = roleManager.getRoleHolders(mRole.getName()); + List holderPackageNames = roleManager.getRoleHoldersAsUser(mRole.getName(), mUser); return new RoleInfo(qualifyingApplicationInfos, holderPackageNames); } diff --git a/src/com/android/packageinstaller/role/utils/PackageUtils.java b/src/com/android/packageinstaller/role/utils/PackageUtils.java index d3fe999e7..912355ec8 100644 --- a/src/com/android/packageinstaller/role/utils/PackageUtils.java +++ b/src/com/android/packageinstaller/role/utils/PackageUtils.java @@ -20,6 +20,7 @@ import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; +import android.os.UserHandle; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -73,4 +74,26 @@ public final class PackageUtils { return null; } } + + /** + * Retrieve the {@link ApplicationInfo} of an application. + * + * @param packageName the package name of the application + * @param user the user of the application + * @param context the {@code Context} to retrieve system services + * + * @return the {@link ApplicationInfo} of the application, or {@code null} if not found + */ + @Nullable + public static ApplicationInfo getApplicationInfoAsUser(@NonNull String packageName, + @NonNull UserHandle user, @NonNull Context context) { + PackageManager packageManager = context.getPackageManager(); + try { + return packageManager.getApplicationInfoAsUser(packageName, + PackageManager.MATCH_DIRECT_BOOT_AWARE + | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, user); + } catch (PackageManager.NameNotFoundException e) { + return null; + } + } } -- GitLab From 6666912df8b50a8b0eb4314cb14ae46737dec524 Mon Sep 17 00:00:00 2001 From: Evan Severson Date: Tue, 18 Dec 2018 10:30:12 -0800 Subject: [PATCH 210/701] Implement 2019 Permission Grant UI Test: atest android.appsecurity.cts.PermissionsHostTest Change-Id: Iea0a1e4d95ac66dbdedf056b104ceaa1bb9c30e2 --- res/layout/grant_permissions.xml | 110 +++++----- res/layout/grant_permissions_content.xml | 51 +---- res/values/dimens.xml | 2 + res/values/strings.xml | 9 + .../GrantPermissionsViewHandlerImpl.java | 190 ++++++------------ 5 files changed, 121 insertions(+), 241 deletions(-) diff --git a/res/layout/grant_permissions.xml b/res/layout/grant_permissions.xml index 697403738..c5636d4ad 100644 --- a/res/layout/grant_permissions.xml +++ b/res/layout/grant_permissions.xml @@ -56,76 +56,60 @@ - + - - - - - + style="@style/PermissionReviewButtonBarSpace"> - + style="@style/PermissionReviewButtonBar"> - + diff --git a/res/values/styles.xml b/res/values/styles.xml index 485f91fe2..7e8a135ad 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -128,7 +128,14 @@ - + + + + + + + + + + + + + + + + diff --git a/res/values/themes.xml b/res/values/themes.xml index cde50ae98..c890f41a2 100644 --- a/res/values/themes.xml +++ b/res/values/themes.xml @@ -30,7 +30,6 @@ parent="@android:style/Theme.DeviceDefault.Settings"> false true - @style/PermissionReviewTitleMessage @style/PreferenceThemeOverlay -- GitLab From 8797468f5c45fd62b399f4bf6df7f419e4e9e15c Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Wed, 6 Feb 2019 15:58:58 -0800 Subject: [PATCH 345/701] Fix browser role fallback. Previously we always return the factory default browser as a fallback (if there is one), however in most cases this will break the previous behavior of clearing the default browser when a new browser is installed. This change changes this behavior to be setting a fallback only if there is only one browser. Test: manual Change-Id: Iac142c2ec0a4fb6eecb55576af817c9589558fe0 --- .../role/model/AssistantRoleBehavior.java | 16 +---- .../role/model/BrowserRoleBehavior.java | 9 +-- .../model/ExclusiveDefaultHolderMixin.java | 59 +++++++++++++++++++ .../role/model/SmsRoleBehavior.java | 21 +------ 4 files changed, 62 insertions(+), 43 deletions(-) create mode 100644 src/com/android/packageinstaller/role/model/ExclusiveDefaultHolderMixin.java diff --git a/src/com/android/packageinstaller/role/model/AssistantRoleBehavior.java b/src/com/android/packageinstaller/role/model/AssistantRoleBehavior.java index aad533d9b..612b47ecd 100644 --- a/src/com/android/packageinstaller/role/model/AssistantRoleBehavior.java +++ b/src/com/android/packageinstaller/role/model/AssistantRoleBehavior.java @@ -39,8 +39,6 @@ import android.util.Xml; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.android.packageinstaller.permission.utils.CollectionUtils; - import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; @@ -65,22 +63,10 @@ public class AssistantRoleBehavior implements RoleBehavior { && !context.getSystemService(ActivityManager.class).isLowRamDevice(); } - @NonNull - @Override - public List getDefaultHolders(@NonNull Role role, @NonNull Context context) { - return CollectionUtils.singletonOrEmpty(getFallbackHolder(role, context)); - } - @Nullable @Override public String getFallbackHolder(@NonNull Role role, @NonNull Context context) { - String defaultPackageName = CollectionUtils.firstOrNull(DefaultRoleHolders.get(context).get( - role.getName())); - if (defaultPackageName == null || !isPackageQualified(role, defaultPackageName, context)) { - return null; - } - - return defaultPackageName; + return ExclusiveDefaultHolderMixin.getDefaultHolder(role, context); } @Nullable diff --git a/src/com/android/packageinstaller/role/model/BrowserRoleBehavior.java b/src/com/android/packageinstaller/role/model/BrowserRoleBehavior.java index 25d547404..637cb2fc9 100644 --- a/src/com/android/packageinstaller/role/model/BrowserRoleBehavior.java +++ b/src/com/android/packageinstaller/role/model/BrowserRoleBehavior.java @@ -28,8 +28,6 @@ import android.util.ArraySet; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.android.packageinstaller.permission.utils.CollectionUtils; - import java.util.ArrayList; import java.util.List; @@ -51,17 +49,12 @@ public class BrowserRoleBehavior implements RoleBehavior { @NonNull @Override public List getDefaultHolders(@NonNull Role role, @NonNull Context context) { - return CollectionUtils.singletonOrEmpty(getFallbackHolder(role, context)); + return ExclusiveDefaultHolderMixin.getDefaultHolders(role, context); } @Nullable @Override public String getFallbackHolder(@NonNull Role role, @NonNull Context context) { - String defaultPackageName = CollectionUtils.firstOrNull(DefaultRoleHolders.get(context).get( - role.getName())); - if (defaultPackageName != null && role.isPackageQualified(defaultPackageName, context)) { - return defaultPackageName; - } List packageNames = role.getQualifyingPackagesAsUser(Process.myUserHandle(), context); if (packageNames.size() == 1) { diff --git a/src/com/android/packageinstaller/role/model/ExclusiveDefaultHolderMixin.java b/src/com/android/packageinstaller/role/model/ExclusiveDefaultHolderMixin.java new file mode 100644 index 000000000..d87a85a63 --- /dev/null +++ b/src/com/android/packageinstaller/role/model/ExclusiveDefaultHolderMixin.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2019 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.packageinstaller.role.model; + +import android.content.Context; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.android.packageinstaller.permission.utils.CollectionUtils; + +import java.util.List; + +/** + * Mixin for {@link RoleBehavior#getDefaultHolders(Role, Context)} that returns a single default + * role holder from {@link DefaultRoleHolders}. + */ +public class ExclusiveDefaultHolderMixin { + + private ExclusiveDefaultHolderMixin() {} + + /** + * @see Role#getDefaultHolders(Context) + */ + @NonNull + public static List getDefaultHolders(@NonNull Role role, @NonNull Context context) { + return CollectionUtils.singletonOrEmpty(getDefaultHolder(role, context)); + } + + /** + * @see Role#getDefaultHolders(Context) + */ + @Nullable + public static String getDefaultHolder(@NonNull Role role, @NonNull Context context) { + String defaultPackageName = CollectionUtils.firstOrNull(DefaultRoleHolders.get(context).get( + role.getName())); + if (defaultPackageName == null) { + return null; + } + if (!role.isPackageQualified(defaultPackageName, context)) { + return null; + } + return defaultPackageName; + } +} diff --git a/src/com/android/packageinstaller/role/model/SmsRoleBehavior.java b/src/com/android/packageinstaller/role/model/SmsRoleBehavior.java index 7a1e76328..b0ab70571 100644 --- a/src/com/android/packageinstaller/role/model/SmsRoleBehavior.java +++ b/src/com/android/packageinstaller/role/model/SmsRoleBehavior.java @@ -57,29 +57,10 @@ public class SmsRoleBehavior implements RoleBehavior { return true; } - @NonNull - @Override - public List getDefaultHolders(@NonNull Role role, @NonNull Context context) { - return CollectionUtils.singletonOrEmpty(getDefaultHolder(role, context)); - } - - @Nullable - private String getDefaultHolder(@NonNull Role role, @NonNull Context context) { - String defaultPackageName = CollectionUtils.firstOrNull(DefaultRoleHolders.get(context).get( - role.getName())); - if (defaultPackageName == null) { - return null; - } - if (!role.isPackageQualified(defaultPackageName, context)) { - return null; - } - return defaultPackageName; - } - @Nullable @Override public String getFallbackHolder(@NonNull Role role, @NonNull Context context) { - String defaultPackageName = getDefaultHolder(role, context); + String defaultPackageName = ExclusiveDefaultHolderMixin.getDefaultHolder(role, context); if (defaultPackageName != null) { return defaultPackageName; } -- GitLab From db1aa626b76b0b5b8b3855f62755a7e8aa27fa93 Mon Sep 17 00:00:00 2001 From: sqian Date: Thu, 17 Jan 2019 13:10:42 -0800 Subject: [PATCH 346/701] Rename Proxy calling app to Call redirecting app. Test: Treehugger Bug: 123038126 Change-Id: I8092cf16b787e3823b31052dbf3edf764d1808fe --- res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 3c8c0e7d1..0a136115a 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -521,7 +521,7 @@ Car mode phone app - Proxy calling app + Call redirecting app Call screening app -- GitLab From 9ab7b9034ac203540254925c11aac981f35aebde Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Wed, 6 Feb 2019 16:40:51 -0800 Subject: [PATCH 347/701] Rename the Proxy calling role to Call redirection. Also drops the _APP suffix in role names, to be consistent with other roles. Test: manual Change-Id: I2142e1c32a7c591679830f76b8d462373d388eb7 --- res/values/strings.xml | 6 +++--- res/xml/roles.xml | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 0a136115a..dba59c058 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -520,11 +520,11 @@ Gallery app Car mode phone app - - Call redirecting app + + Call redirecting app Call screening app - + Call companion app Assist app diff --git a/res/xml/roles.xml b/res/xml/roles.xml index eef09c94a..58715d421 100644 --- a/res/xml/roles.xml +++ b/res/xml/roles.xml @@ -379,7 +379,7 @@ @@ -398,9 +398,9 @@ + label="@string/role_label_call_redirection"> @@ -412,7 +412,7 @@ @@ -426,7 +426,7 @@ -- GitLab From 2b8e6c775256b71c5aec5d9dca313101a2bf9426 Mon Sep 17 00:00:00 2001 From: Brett Chabot Date: Thu, 7 Feb 2019 13:40:05 -0800 Subject: [PATCH 348/701] Migrate packages/apps/PermissionController to androidx.test See go/jetpack-test-android-migration Also remove unnecessary cts build dependencies, that are complicating the CTS migration to androidx.test Test: make PermissionControllerTest Change-Id: Ic01ef4a6bfde627cea5fdcd20e78f168f7d77f43 --- test/instrumentation/Android.mk | 2 -- test/instrumentation/AndroidManifest.xml | 2 +- test/instrumentation/AndroidTest.xml | 2 +- .../incident/RequestConfirmationTest.java | 2 +- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/test/instrumentation/Android.mk b/test/instrumentation/Android.mk index d09402d71..5bc10244e 100644 --- a/test/instrumentation/Android.mk +++ b/test/instrumentation/Android.mk @@ -27,8 +27,6 @@ LOCAL_JAVA_LIBRARIES := android.test.runner.stubs LOCAL_PROGUARD_ENABLED := disabled LOCAL_STATIC_JAVA_LIBRARIES := \ - ctstestrunner \ - compatibility-device-util \ androidx.annotation_annotation \ androidx.test.runner \ androidx.test.rules \ diff --git a/test/instrumentation/AndroidManifest.xml b/test/instrumentation/AndroidManifest.xml index ba4dfcff2..f2686b1b7 100644 --- a/test/instrumentation/AndroidManifest.xml +++ b/test/instrumentation/AndroidManifest.xml @@ -20,6 +20,6 @@ - diff --git a/test/instrumentation/AndroidTest.xml b/test/instrumentation/AndroidTest.xml index 6d6d0c09a..23e9cb58f 100644 --- a/test/instrumentation/AndroidTest.xml +++ b/test/instrumentation/AndroidTest.xml @@ -25,6 +25,6 @@ diff --git a/test/instrumentation/src/com/android/permissioncontrollertesthelper/incident/RequestConfirmationTest.java b/test/instrumentation/src/com/android/permissioncontrollertesthelper/incident/RequestConfirmationTest.java index b49877b7e..347ef170e 100644 --- a/test/instrumentation/src/com/android/permissioncontrollertesthelper/incident/RequestConfirmationTest.java +++ b/test/instrumentation/src/com/android/permissioncontrollertesthelper/incident/RequestConfirmationTest.java @@ -19,9 +19,9 @@ import android.content.Context; import android.content.res.Resources; import android.os.ConditionVariable; import android.os.IncidentManager; -import android.support.test.InstrumentationRegistry; import android.util.Log; +import androidx.test.InstrumentationRegistry; import androidx.test.uiautomator.By; import androidx.test.uiautomator.BySelector; import androidx.test.uiautomator.UiDevice; -- GitLab From ffa1ad0ab6b0dc7118dd1b4de115148c725357fe Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Thu, 7 Feb 2019 20:04:12 -0800 Subject: [PATCH 349/701] Use separate config entries for default role holders. Using a single config_defaultRoleHolders turned out to be problematic and error-prone when mixed with multiple overlays, so split it into separate config entries. Bug: 122730135 Test: build Change-Id: I4125781ec1989e0bcf90d503ae97472468cd4fb6 --- .../role/model/AssistantRoleBehavior.java | 4 +- .../role/model/BrowserRoleBehavior.java | 3 +- .../role/model/DefaultRoleHolders.java | 98 ------------------- .../model/ExclusiveDefaultHolderMixin.java | 30 ++++-- .../role/model/SmsRoleBehavior.java | 3 +- 5 files changed, 27 insertions(+), 111 deletions(-) delete mode 100644 src/com/android/packageinstaller/role/model/DefaultRoleHolders.java diff --git a/src/com/android/packageinstaller/role/model/AssistantRoleBehavior.java b/src/com/android/packageinstaller/role/model/AssistantRoleBehavior.java index 612b47ecd..1d0e9ef07 100644 --- a/src/com/android/packageinstaller/role/model/AssistantRoleBehavior.java +++ b/src/com/android/packageinstaller/role/model/AssistantRoleBehavior.java @@ -16,7 +16,6 @@ package com.android.packageinstaller.role.model; - import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; import static org.xmlpull.v1.XmlPullParser.START_TAG; @@ -66,7 +65,8 @@ public class AssistantRoleBehavior implements RoleBehavior { @Nullable @Override public String getFallbackHolder(@NonNull Role role, @NonNull Context context) { - return ExclusiveDefaultHolderMixin.getDefaultHolder(role, context); + return ExclusiveDefaultHolderMixin.getDefaultHolder(role, "config_defaultAssistant", + context); } @Nullable diff --git a/src/com/android/packageinstaller/role/model/BrowserRoleBehavior.java b/src/com/android/packageinstaller/role/model/BrowserRoleBehavior.java index 637cb2fc9..94a104d48 100644 --- a/src/com/android/packageinstaller/role/model/BrowserRoleBehavior.java +++ b/src/com/android/packageinstaller/role/model/BrowserRoleBehavior.java @@ -49,7 +49,8 @@ public class BrowserRoleBehavior implements RoleBehavior { @NonNull @Override public List getDefaultHolders(@NonNull Role role, @NonNull Context context) { - return ExclusiveDefaultHolderMixin.getDefaultHolders(role, context); + return ExclusiveDefaultHolderMixin.getDefaultHolders(role, "config_defaultBrowser", + context); } @Nullable diff --git a/src/com/android/packageinstaller/role/model/DefaultRoleHolders.java b/src/com/android/packageinstaller/role/model/DefaultRoleHolders.java deleted file mode 100644 index d4b934e69..000000000 --- a/src/com/android/packageinstaller/role/model/DefaultRoleHolders.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2019 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.packageinstaller.role.model; - -import android.content.Context; -import android.util.ArrayMap; -import android.util.ArraySet; -import android.util.Log; - -import androidx.annotation.NonNull; - -import java.util.Arrays; -import java.util.List; - -/** - * Provides access to all the default role holders. - */ -public class DefaultRoleHolders { - - private static final String LOG_TAG = DefaultRoleHolders.class.getSimpleName(); - - @NonNull - private static final Object sLock = new Object(); - - private static ArrayMap> sDefaultRoleHolders; - - /** - * Get the default role holders. - * - * @param context the {@code Context} used to read the system resource - * - * @return a map from role name to a list of package names of the default holders - */ - @NonNull - public static ArrayMap> get(@NonNull Context context) { - synchronized (sLock) { - if (sDefaultRoleHolders == null) { - sDefaultRoleHolders = load(context); - } - return sDefaultRoleHolders; - } - } - - @NonNull - private static ArrayMap> load(@NonNull Context context) { - ArrayMap> defaultRoleHolders = new ArrayMap<>(); - String[] items = context.getResources().getStringArray( - android.R.array.config_defaultRoleHolders); - int itemsLength = items.length; - for (int i = 0; i < itemsLength; i++) { - String item = items[i]; - - item = item.trim(); - String[] roleNameAndPackageNames = item.split("\\s*:\\s*", 2); - if (roleNameAndPackageNames.length != 2) { - Log.e(LOG_TAG, "Invalid item: " + item); - continue; - } - String roleName = roleNameAndPackageNames[0]; - if (roleName.isEmpty()) { - Log.e(LOG_TAG, "Empty role name: " + item); - continue; - } - if (defaultRoleHolders.containsKey(roleName)) { - Log.e(LOG_TAG, "Duplicate role name: " + roleName); - continue; - } - String packageNamesString = roleNameAndPackageNames[1]; - if (packageNamesString.isEmpty()) { - Log.e(LOG_TAG, "Empty package names: " + item); - continue; - } - List packageNames = Arrays.asList(packageNamesString.split("\\s*,\\s*")); - ArraySet uniquePackageNames = new ArraySet<>(packageNames); - if (packageNames.size() != uniquePackageNames.size()) { - Log.e(LOG_TAG, "Duplicate package names: " + packageNamesString); - packageNames.clear(); - packageNames.addAll(uniquePackageNames); - } - defaultRoleHolders.put(roleName, packageNames); - } - return defaultRoleHolders; - } -} diff --git a/src/com/android/packageinstaller/role/model/ExclusiveDefaultHolderMixin.java b/src/com/android/packageinstaller/role/model/ExclusiveDefaultHolderMixin.java index d87a85a63..320d5def3 100644 --- a/src/com/android/packageinstaller/role/model/ExclusiveDefaultHolderMixin.java +++ b/src/com/android/packageinstaller/role/model/ExclusiveDefaultHolderMixin.java @@ -17,6 +17,9 @@ package com.android.packageinstaller.role.model; import android.content.Context; +import android.content.res.Resources; +import android.text.TextUtils; +import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -27,33 +30,42 @@ import java.util.List; /** * Mixin for {@link RoleBehavior#getDefaultHolders(Role, Context)} that returns a single default - * role holder from {@link DefaultRoleHolders}. + * role holder from the corresponding string resource. */ public class ExclusiveDefaultHolderMixin { + private static final String LOG_TAG = ExclusiveDefaultHolderMixin.class.getSimpleName(); + private ExclusiveDefaultHolderMixin() {} /** * @see Role#getDefaultHolders(Context) */ @NonNull - public static List getDefaultHolders(@NonNull Role role, @NonNull Context context) { - return CollectionUtils.singletonOrEmpty(getDefaultHolder(role, context)); + public static List getDefaultHolders(@NonNull Role role, @NonNull String resourceName, + @NonNull Context context) { + return CollectionUtils.singletonOrEmpty(getDefaultHolder(role, resourceName, context)); } /** * @see Role#getDefaultHolders(Context) */ @Nullable - public static String getDefaultHolder(@NonNull Role role, @NonNull Context context) { - String defaultPackageName = CollectionUtils.firstOrNull(DefaultRoleHolders.get(context).get( - role.getName())); - if (defaultPackageName == null) { + public static String getDefaultHolder(@NonNull Role role, @NonNull String resourceName, + @NonNull Context context) { + Resources resources = context.getResources(); + int resourceId = resources.getIdentifier(resourceName, "string", "android"); + if (resourceId == 0) { + Log.w(LOG_TAG, "Cannot find resource for default holder: " + resourceName); + return null; + } + String packageName = resources.getString(resourceId); + if (TextUtils.isEmpty(packageName)) { return null; } - if (!role.isPackageQualified(defaultPackageName, context)) { + if (!role.isPackageQualified(packageName, context)) { return null; } - return defaultPackageName; + return packageName; } } diff --git a/src/com/android/packageinstaller/role/model/SmsRoleBehavior.java b/src/com/android/packageinstaller/role/model/SmsRoleBehavior.java index b0ab70571..e14cf5cab 100644 --- a/src/com/android/packageinstaller/role/model/SmsRoleBehavior.java +++ b/src/com/android/packageinstaller/role/model/SmsRoleBehavior.java @@ -60,7 +60,8 @@ public class SmsRoleBehavior implements RoleBehavior { @Nullable @Override public String getFallbackHolder(@NonNull Role role, @NonNull Context context) { - String defaultPackageName = ExclusiveDefaultHolderMixin.getDefaultHolder(role, context); + String defaultPackageName = ExclusiveDefaultHolderMixin.getDefaultHolder(role, + "config_defaultSms", context); if (defaultPackageName != null) { return defaultPackageName; } -- GitLab From 3c4752fa88dbef436f6b42366048e83737d3e9e2 Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Fri, 8 Feb 2019 12:29:01 -0800 Subject: [PATCH 350/701] Add default for music and gallery app. Also rearrange the order of the roles to be consistent. Bug: 123994674 Test: manual Change-Id: Iaa2fe8f24bd3b4ad9e2972a3b74dce8799bbacaf --- res/values/strings.xml | 4 +- res/xml/roles.xml | 90 ++++++++++--------- .../role/model/GalleryRoleBehavior.java | 36 ++++++++ .../role/model/MusicRoleBehavior.java | 35 ++++++++ .../role/model/SmsRoleBehavior.java | 1 - 5 files changed, 122 insertions(+), 44 deletions(-) create mode 100644 src/com/android/packageinstaller/role/model/GalleryRoleBehavior.java create mode 100644 src/com/android/packageinstaller/role/model/MusicRoleBehavior.java diff --git a/res/values/strings.xml b/res/values/strings.xml index dba59c058..aba84ac9a 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -504,6 +504,8 @@ + + Assist app Browser app @@ -526,8 +528,6 @@ Call screening app Call companion app - - Assist app WON\'T BE RELEASED: SMS access app diff --git a/res/xml/roles.xml b/res/xml/roles.xml index 58715d421..e46d0e20e 100644 --- a/res/xml/roles.xml +++ b/res/xml/roles.xml @@ -77,6 +77,45 @@ + + + + + + + + + + + - - - - - - - - getDefaultHolders(@NonNull Role role, @NonNull Context context) { + return ExclusiveDefaultHolderMixin.getDefaultHolders(role, "config_defaultGallery", + context); + } +} diff --git a/src/com/android/packageinstaller/role/model/MusicRoleBehavior.java b/src/com/android/packageinstaller/role/model/MusicRoleBehavior.java new file mode 100644 index 000000000..d24c616f9 --- /dev/null +++ b/src/com/android/packageinstaller/role/model/MusicRoleBehavior.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2019 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.packageinstaller.role.model; + +import android.content.Context; + +import androidx.annotation.NonNull; + +import java.util.List; + +/** + * Class for behavior of the music role. + */ +public class MusicRoleBehavior implements RoleBehavior { + + @NonNull + @Override + public List getDefaultHolders(@NonNull Role role, @NonNull Context context) { + return ExclusiveDefaultHolderMixin.getDefaultHolders(role, "config_defaultMusic", context); + } +} diff --git a/src/com/android/packageinstaller/role/model/SmsRoleBehavior.java b/src/com/android/packageinstaller/role/model/SmsRoleBehavior.java index e14cf5cab..0485e1c18 100644 --- a/src/com/android/packageinstaller/role/model/SmsRoleBehavior.java +++ b/src/com/android/packageinstaller/role/model/SmsRoleBehavior.java @@ -35,7 +35,6 @@ import java.util.List; * @see com.android.settings.applications.DefaultAppSettings * @see com.android.settings.applications.defaultapps.DefaultSmsPreferenceController * @see com.android.settings.applications.defaultapps.DefaultSmsPicker - * */ public class SmsRoleBehavior implements RoleBehavior { -- GitLab From 7ceb0db76f19db70db26e74c8c28ef8a6a232906 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Fri, 8 Feb 2019 13:59:48 -0800 Subject: [PATCH 351/701] Handle the intent to open the app permission toggle screen. Test: Modify code to use the intent and it still launches the screen. Change-Id: Ic8b0ea0325b03e16764c9957f44f1b978d37edd8 --- AndroidManifest.xml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index e520a778c..b0cf9b85c 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -112,7 +112,12 @@ + android:permission="android.permission.GRANT_RUNTIME_PERMISSIONS"> + + + + + Date: Fri, 8 Feb 2019 17:05:50 -0800 Subject: [PATCH 352/701] Make sure a default role holder is a system app. Having a non-system app specified as a default role holder can be dangerous. Test: build Change-Id: I28b30cb1ee9c14c436c492c997be520a64f73675 --- .../role/model/ExclusiveDefaultHolderMixin.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/com/android/packageinstaller/role/model/ExclusiveDefaultHolderMixin.java b/src/com/android/packageinstaller/role/model/ExclusiveDefaultHolderMixin.java index 320d5def3..aeaf102d3 100644 --- a/src/com/android/packageinstaller/role/model/ExclusiveDefaultHolderMixin.java +++ b/src/com/android/packageinstaller/role/model/ExclusiveDefaultHolderMixin.java @@ -17,6 +17,7 @@ package com.android.packageinstaller.role.model; import android.content.Context; +import android.content.pm.ApplicationInfo; import android.content.res.Resources; import android.text.TextUtils; import android.util.Log; @@ -25,6 +26,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.packageinstaller.permission.utils.CollectionUtils; +import com.android.packageinstaller.role.utils.PackageUtils; import java.util.List; @@ -63,6 +65,19 @@ public class ExclusiveDefaultHolderMixin { if (TextUtils.isEmpty(packageName)) { return null; } + + ApplicationInfo applicationInfo = PackageUtils.getApplicationInfo(packageName, context); + if (applicationInfo == null) { + Log.w(LOG_TAG, "Cannot get ApplicationInfo for default holder, config: " + resourceName + + ", package: " + packageName); + return null; + } + if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { + Log.w(LOG_TAG, "Default holder is not a system app, config: " + resourceName + + ", package: " + packageName); + return null; + } + if (!role.isPackageQualified(packageName, context)) { return null; } -- GitLab From bb7aff3089aa3ce32b7780500da14abdbbf6c081 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Fri, 8 Feb 2019 17:06:56 -0800 Subject: [PATCH 353/701] Import translations. DO NOT MERGE Change-Id: I291ed6423f8d7cbba94036c36f18aca6e4f228f3 Auto-generated-cl: translation import --- res/values-af/strings.xml | 49 +-- res/values-am/strings.xml | 49 +-- res/values-ar/strings.xml | 53 +-- res/values-as/strings.xml | 49 +-- res/values-az/strings.xml | 49 +-- res/values-b+sr+Latn/strings.xml | 50 +-- res/values-be/strings.xml | 51 +-- res/values-bg/strings.xml | 49 +-- res/values-bn/strings.xml | 49 +-- res/values-bs-television/strings.xml | 4 +- res/values-bs/strings.xml | 52 +-- res/values-ca/strings.xml | 49 +-- res/values-cs/strings.xml | 51 +-- res/values-da/strings.xml | 49 +-- res/values-de/strings.xml | 49 +-- res/values-el/strings.xml | 49 +-- res/values-en-rAU/strings.xml | 49 +-- res/values-en-rCA/strings.xml | 49 +-- res/values-en-rGB/strings.xml | 49 +-- res/values-en-rIN/strings.xml | 49 +-- res/values-en-rXC-television/strings.xml | 18 +- res/values-en-rXC-watch/strings.xml | 12 +- res/values-en-rXC/strings.xml | 349 +++++++++--------- res/values-es-rUS/strings.xml | 49 +-- res/values-es/strings.xml | 49 +-- res/values-et/strings.xml | 49 +-- res/values-eu/strings.xml | 49 +-- res/values-fa/strings.xml | 49 +-- res/values-fi/strings.xml | 49 +-- res/values-fr-rCA/strings.xml | 49 +-- res/values-fr/strings.xml | 49 +-- res/values-gl/strings.xml | 49 +-- res/values-gu/strings.xml | 49 +-- res/values-hi/strings.xml | 49 +-- res/values-hr/strings.xml | 50 +-- res/values-hu/strings.xml | 49 +-- res/values-hy/strings.xml | 49 +-- res/values-in/strings.xml | 49 +-- res/values-is/strings.xml | 49 +-- res/values-it/strings.xml | 49 +-- res/values-iw/strings.xml | 51 +-- res/values-ja/strings.xml | 49 +-- res/values-ka/strings.xml | 49 +-- res/values-kk/strings.xml | 49 +-- res/values-km/strings.xml | 49 +-- res/values-kn/strings.xml | 49 +-- res/values-ko/strings.xml | 49 +-- res/values-ky/strings.xml | 49 +-- res/values-lo/strings.xml | 49 +-- res/values-lt/strings.xml | 51 +-- res/values-lv/strings.xml | 50 +-- res/values-mk/strings.xml | 49 +-- res/values-ml/strings.xml | 49 +-- res/values-mn/strings.xml | 49 +-- res/values-mr/strings.xml | 49 +-- res/values-ms/strings.xml | 49 +-- res/values-my/strings.xml | 49 +-- res/values-nb/strings.xml | 49 +-- res/values-ne/strings.xml | 49 +-- res/values-nl/strings.xml | 49 +-- res/values-or/strings.xml | 49 +-- res/values-pa/strings.xml | 49 +-- res/values-pl/strings.xml | 51 +-- res/values-pt-rBR/strings.xml | 49 +-- res/values-pt-rPT/strings.xml | 49 +-- res/values-pt/strings.xml | 49 +-- res/values-ro/strings.xml | 50 +-- res/values-ru/strings.xml | 51 +-- res/values-si/strings.xml | 49 +-- res/values-sk/strings.xml | 51 +-- res/values-sl/strings.xml | 51 +-- res/values-sq/strings.xml | 49 +-- res/values-sr/strings.xml | 50 +-- res/values-sv/strings.xml | 49 +-- res/values-sw/strings.xml | 49 +-- res/values-ta/strings.xml | 49 +-- res/values-te/strings.xml | 49 +-- res/values-th/strings.xml | 49 +-- res/values-tl/strings.xml | 49 +-- res/values-tr/strings.xml | 49 +-- res/values-uk/strings.xml | 51 +-- res/values-ur/strings.xml | 49 +-- res/values-uz/strings.xml | 49 +-- res/values-vi/strings.xml | 49 +-- res/values-zh-rCN/strings.xml | 49 +-- res/values-zh-rHK/strings.xml | 49 +-- res/values-zh-rTW/strings.xml | 49 +-- res/values-zu/strings.xml | 49 +-- .../instrumentation/res/values-af/strings.xml | 20 + .../instrumentation/res/values-am/strings.xml | 20 + .../instrumentation/res/values-ar/strings.xml | 20 + .../instrumentation/res/values-as/strings.xml | 20 + .../instrumentation/res/values-az/strings.xml | 20 + .../res/values-b+sr+Latn/strings.xml | 20 + .../instrumentation/res/values-be/strings.xml | 20 + .../instrumentation/res/values-bg/strings.xml | 20 + .../instrumentation/res/values-bn/strings.xml | 20 + .../instrumentation/res/values-bs/strings.xml | 20 + .../instrumentation/res/values-ca/strings.xml | 20 + .../instrumentation/res/values-cs/strings.xml | 20 + .../instrumentation/res/values-da/strings.xml | 20 + .../instrumentation/res/values-de/strings.xml | 20 + .../instrumentation/res/values-el/strings.xml | 20 + .../res/values-en-rAU/strings.xml | 20 + .../res/values-en-rCA/strings.xml | 20 + .../res/values-en-rGB/strings.xml | 20 + .../res/values-en-rIN/strings.xml | 20 + .../res/values-en-rXC/strings.xml | 20 + .../res/values-es-rUS/strings.xml | 20 + .../instrumentation/res/values-es/strings.xml | 20 + .../instrumentation/res/values-et/strings.xml | 20 + .../instrumentation/res/values-eu/strings.xml | 20 + .../instrumentation/res/values-fa/strings.xml | 20 + .../instrumentation/res/values-fi/strings.xml | 20 + .../res/values-fr-rCA/strings.xml | 20 + .../instrumentation/res/values-fr/strings.xml | 20 + .../instrumentation/res/values-gl/strings.xml | 20 + .../instrumentation/res/values-gu/strings.xml | 20 + .../instrumentation/res/values-hi/strings.xml | 20 + .../instrumentation/res/values-hr/strings.xml | 20 + .../instrumentation/res/values-hu/strings.xml | 20 + .../instrumentation/res/values-hy/strings.xml | 20 + .../instrumentation/res/values-in/strings.xml | 20 + .../instrumentation/res/values-is/strings.xml | 20 + .../instrumentation/res/values-it/strings.xml | 20 + .../instrumentation/res/values-iw/strings.xml | 20 + .../instrumentation/res/values-ja/strings.xml | 20 + .../instrumentation/res/values-ka/strings.xml | 20 + .../instrumentation/res/values-kk/strings.xml | 20 + .../instrumentation/res/values-km/strings.xml | 20 + .../instrumentation/res/values-kn/strings.xml | 20 + .../instrumentation/res/values-ko/strings.xml | 20 + .../instrumentation/res/values-ky/strings.xml | 20 + .../instrumentation/res/values-lo/strings.xml | 20 + .../instrumentation/res/values-lt/strings.xml | 20 + .../instrumentation/res/values-lv/strings.xml | 20 + .../instrumentation/res/values-mk/strings.xml | 20 + .../instrumentation/res/values-ml/strings.xml | 20 + .../instrumentation/res/values-mn/strings.xml | 20 + .../instrumentation/res/values-mr/strings.xml | 20 + .../instrumentation/res/values-ms/strings.xml | 20 + .../instrumentation/res/values-my/strings.xml | 20 + .../instrumentation/res/values-nb/strings.xml | 20 + .../instrumentation/res/values-ne/strings.xml | 20 + .../instrumentation/res/values-nl/strings.xml | 20 + .../instrumentation/res/values-or/strings.xml | 20 + .../instrumentation/res/values-pa/strings.xml | 20 + .../instrumentation/res/values-pl/strings.xml | 20 + .../res/values-pt-rBR/strings.xml | 20 + .../res/values-pt-rPT/strings.xml | 20 + .../instrumentation/res/values-pt/strings.xml | 20 + .../instrumentation/res/values-ro/strings.xml | 20 + .../instrumentation/res/values-ru/strings.xml | 20 + .../instrumentation/res/values-si/strings.xml | 20 + .../instrumentation/res/values-sk/strings.xml | 20 + .../instrumentation/res/values-sl/strings.xml | 20 + .../instrumentation/res/values-sq/strings.xml | 20 + .../instrumentation/res/values-sr/strings.xml | 20 + .../instrumentation/res/values-sv/strings.xml | 20 + .../instrumentation/res/values-sw/strings.xml | 20 + .../instrumentation/res/values-ta/strings.xml | 20 + .../instrumentation/res/values-te/strings.xml | 20 + .../instrumentation/res/values-th/strings.xml | 20 + .../instrumentation/res/values-tl/strings.xml | 20 + .../instrumentation/res/values-tr/strings.xml | 20 + .../instrumentation/res/values-uk/strings.xml | 20 + .../instrumentation/res/values-ur/strings.xml | 20 + .../instrumentation/res/values-uz/strings.xml | 20 + .../instrumentation/res/values-vi/strings.xml | 20 + .../res/values-zh-rCN/strings.xml | 20 + .../res/values-zh-rHK/strings.xml | 20 + .../res/values-zh-rTW/strings.xml | 20 + .../instrumentation/res/values-zu/strings.xml | 20 + 173 files changed, 3401 insertions(+), 2828 deletions(-) create mode 100644 test/instrumentation/res/values-af/strings.xml create mode 100644 test/instrumentation/res/values-am/strings.xml create mode 100644 test/instrumentation/res/values-ar/strings.xml create mode 100644 test/instrumentation/res/values-as/strings.xml create mode 100644 test/instrumentation/res/values-az/strings.xml create mode 100644 test/instrumentation/res/values-b+sr+Latn/strings.xml create mode 100644 test/instrumentation/res/values-be/strings.xml create mode 100644 test/instrumentation/res/values-bg/strings.xml create mode 100644 test/instrumentation/res/values-bn/strings.xml create mode 100644 test/instrumentation/res/values-bs/strings.xml create mode 100644 test/instrumentation/res/values-ca/strings.xml create mode 100644 test/instrumentation/res/values-cs/strings.xml create mode 100644 test/instrumentation/res/values-da/strings.xml create mode 100644 test/instrumentation/res/values-de/strings.xml create mode 100644 test/instrumentation/res/values-el/strings.xml create mode 100644 test/instrumentation/res/values-en-rAU/strings.xml create mode 100644 test/instrumentation/res/values-en-rCA/strings.xml create mode 100644 test/instrumentation/res/values-en-rGB/strings.xml create mode 100644 test/instrumentation/res/values-en-rIN/strings.xml create mode 100644 test/instrumentation/res/values-en-rXC/strings.xml create mode 100644 test/instrumentation/res/values-es-rUS/strings.xml create mode 100644 test/instrumentation/res/values-es/strings.xml create mode 100644 test/instrumentation/res/values-et/strings.xml create mode 100644 test/instrumentation/res/values-eu/strings.xml create mode 100644 test/instrumentation/res/values-fa/strings.xml create mode 100644 test/instrumentation/res/values-fi/strings.xml create mode 100644 test/instrumentation/res/values-fr-rCA/strings.xml create mode 100644 test/instrumentation/res/values-fr/strings.xml create mode 100644 test/instrumentation/res/values-gl/strings.xml create mode 100644 test/instrumentation/res/values-gu/strings.xml create mode 100644 test/instrumentation/res/values-hi/strings.xml create mode 100644 test/instrumentation/res/values-hr/strings.xml create mode 100644 test/instrumentation/res/values-hu/strings.xml create mode 100644 test/instrumentation/res/values-hy/strings.xml create mode 100644 test/instrumentation/res/values-in/strings.xml create mode 100644 test/instrumentation/res/values-is/strings.xml create mode 100644 test/instrumentation/res/values-it/strings.xml create mode 100644 test/instrumentation/res/values-iw/strings.xml create mode 100644 test/instrumentation/res/values-ja/strings.xml create mode 100644 test/instrumentation/res/values-ka/strings.xml create mode 100644 test/instrumentation/res/values-kk/strings.xml create mode 100644 test/instrumentation/res/values-km/strings.xml create mode 100644 test/instrumentation/res/values-kn/strings.xml create mode 100644 test/instrumentation/res/values-ko/strings.xml create mode 100644 test/instrumentation/res/values-ky/strings.xml create mode 100644 test/instrumentation/res/values-lo/strings.xml create mode 100644 test/instrumentation/res/values-lt/strings.xml create mode 100644 test/instrumentation/res/values-lv/strings.xml create mode 100644 test/instrumentation/res/values-mk/strings.xml create mode 100644 test/instrumentation/res/values-ml/strings.xml create mode 100644 test/instrumentation/res/values-mn/strings.xml create mode 100644 test/instrumentation/res/values-mr/strings.xml create mode 100644 test/instrumentation/res/values-ms/strings.xml create mode 100644 test/instrumentation/res/values-my/strings.xml create mode 100644 test/instrumentation/res/values-nb/strings.xml create mode 100644 test/instrumentation/res/values-ne/strings.xml create mode 100644 test/instrumentation/res/values-nl/strings.xml create mode 100644 test/instrumentation/res/values-or/strings.xml create mode 100644 test/instrumentation/res/values-pa/strings.xml create mode 100644 test/instrumentation/res/values-pl/strings.xml create mode 100644 test/instrumentation/res/values-pt-rBR/strings.xml create mode 100644 test/instrumentation/res/values-pt-rPT/strings.xml create mode 100644 test/instrumentation/res/values-pt/strings.xml create mode 100644 test/instrumentation/res/values-ro/strings.xml create mode 100644 test/instrumentation/res/values-ru/strings.xml create mode 100644 test/instrumentation/res/values-si/strings.xml create mode 100644 test/instrumentation/res/values-sk/strings.xml create mode 100644 test/instrumentation/res/values-sl/strings.xml create mode 100644 test/instrumentation/res/values-sq/strings.xml create mode 100644 test/instrumentation/res/values-sr/strings.xml create mode 100644 test/instrumentation/res/values-sv/strings.xml create mode 100644 test/instrumentation/res/values-sw/strings.xml create mode 100644 test/instrumentation/res/values-ta/strings.xml create mode 100644 test/instrumentation/res/values-te/strings.xml create mode 100644 test/instrumentation/res/values-th/strings.xml create mode 100644 test/instrumentation/res/values-tl/strings.xml create mode 100644 test/instrumentation/res/values-tr/strings.xml create mode 100644 test/instrumentation/res/values-uk/strings.xml create mode 100644 test/instrumentation/res/values-ur/strings.xml create mode 100644 test/instrumentation/res/values-uz/strings.xml create mode 100644 test/instrumentation/res/values-vi/strings.xml create mode 100644 test/instrumentation/res/values-zh-rCN/strings.xml create mode 100644 test/instrumentation/res/values-zh-rHK/strings.xml create mode 100644 test/instrumentation/res/values-zh-rTW/strings.xml create mode 100644 test/instrumentation/res/values-zu/strings.xml diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml index 675a9c838..af0a1c66f 100644 --- a/res/values-af/strings.xml +++ b/res/values-af/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "Toptoestemminggebruik in afgelope 15 minute" "Toptoestemminggebruik in afgelope 1 minuut" "Programme" - - - - + "Gefiltreer volgens: %1$s" + "Verwyder filter" "Filtreer volgens" "Filtreer volgens toestemmings" "Meeste toestemmings" "Meeste toegange" "Onlangs" - - + "Herlaai" "Programtoestemmingsgebruik" "Toegang: %1$s keer. Totale tydsduur: %2$s. %3$s gelede laas gebruik." "Toegang: %1$s keer. %2$s gelede laas gebruik." @@ -137,11 +134,9 @@ "%1$s het %3$s gelede toegang tot jou %2$s verkry." "%1$s het nie toegang gekry tot jou %2$s nie." "Bekyk gedetailleerde toestemmingsgebruik" - - + "Jongste toegang: %1$s" "Toegelaat" - - + "Net toegelaat wanneer dit gebruik word" "Geweier" "Sien gedetailleerde gebruik" @@ -165,22 +160,6 @@ "Toestemmingonthounotas" "%s gebruik jou ligging" "Hierdie program het altyd toegang tot jou ligging. Tik om te verander." - "Die programontwikkelaar sê jou data kan:" - "As jy nie hou van hoe hierdie programontwikkelaar jou data gebruik nie, kan jy die toestemming weier." - "Gaan na %s toe vir meer inligting." - "Opgelaai word na wolk toe" - "Opgelaai word na wolk toe wanneer jy dit uitdruklik toelaat" - "Gedeel word met adverteerders of besighede" - "Gedeel word met adverteerders of besighede wanneer jy dit uitdruklik toelaat" - "Gebruik word vir monetisering" - "Gebruik word vir monetisering wanneer jy dit uitdruklik toelaat" - "Vir altyd gestoor en ontleed word" - "Gestoor en ontleed word vir \'n tydsduur wat jy spesifiseer" - - Gestoor en ontleed vir %s weke - Gestoor en ontleed vir 1 week - - "Die programontwikkelaar het nie gespesifiseer hoe die program jou data gebruik nie." "Net terwyl die program gebruik word" "Geen toestemmings toegelaat nie" "Geen toestemmings geweier nie" @@ -205,10 +184,18 @@ "Musiekprogram" "Galeryprogram" "Motormodus-foonprogram" - "Instaanbedieneroproep-program" + + "Oproepsiftingsprogram" "Oproepmetgeselprogram" - - + "Bystandprogram" + "Motorprojeksie-program" "Let wel: As jy jou toestel herbegin en \'n skermslot is gestel, kan hierdie program nie begin totdat jy jou toestel ontsluit nie." + "Deel ontfoutingsdata" + "Deel gedetailleerde ontfoutingsdata?" + "%1$s wil graag ontfoutingsinligting oplaai." + "Deel ontfoutingsdata" + "%1$s versoek tans om \'n foutverslag wat op %2$s om %3$s op hierdie toestel gegenereer is, op te laai. Foutverslae sluit persoonlike inligting oor jou toestel of wat deur programme aangemeld is in, byvoorbeeld gebruikername, liggingdata, toestelidentifiseerders en netwerkinligting. Deel foutverslae net met mense en programme wat jy met hierdie inligting vertrou. Laat %4$s toe om \'n foutverslag op te laai?" + "Laat toe" + "Weier" diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml index 82c7e7a47..c931b3433 100644 --- a/res/values-am/strings.xml +++ b/res/values-am/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "ባለፉት 15 ደቂቃዎች ውስጥ የነበረ ከፍተኛ የፈቃድ አጠቃቀም" "ባለፈው 1 ደቂቃ ውስጥ ከፍተኛ የፈቃድ አጠቃቀም" "መተግበሪያዎች" - - - - + "የተጣራው በ፦ %1$s" + "ማጣሪያን አስወግድ" "አጣራ በ" "በፈቃዶች አጣራ" "አብዛኛዎቹ ፈቃዶች" "አብዛኛዎቹ መድረሶች" "የቅርብ ጊዜ" - - + "አድስ" "የመተግበሪያ ፈቃዶች አጠቃቀም" "ድረስበት፦ %1$s ጊዜ። አጠቃላይ ቆይታ ጊዜ፦ %2$s። ለመጨረሻ ጥቅም ላይ የዋለው ከ%3$s በፊት።" "ድረስበት፦ %1$s ጊዜ። ለመጨረሻ ጥቅም ላይ የዋለው ከ%2$s በፊት።" @@ -137,11 +134,9 @@ "%1$s%3$s በፊት የእርስዎን %2$s ደርሶ ነበር።" "%1$s የእርስዎን %2$s አልደረሰበትም።" "ዝርዝር የፈቃዶች አጠቃቀምን ይመልከቱ" - - + "የመጨረሻ መዳረሻ፦ %1$s" "ይፈቀዳል" - - + "ስራ ላይ ሲውል ብቻ የሚፈቀድ" "ውድቅ ተደርጓል" "በዝርዝር የቀረበ አጠቃቀምን ይመልከቱ" @@ -165,22 +160,6 @@ "የፈቃድ አስታዋሾች" "%s የእርስዎን አካባቢ እየተጠቀመ ነበር" "ይህ መተግበሪያ በማንኛውም ጊዜ አካባቢዎን መድረስ ይችላል። ለመቀየር መታ ያድርጉ።" - "የመተግበሪያው ገንቢ የእርስዎ ውሂብ እንዲህ ሊሆን ይችላል ይላል፦" - "የዚህ መተግበሪያ ገንቢ የእርስዎን ውሂብ የሚጠቀምበት ሁኔታ ደስ ካላልዎት ፈቃዱን መከልከል ይችላሉ።" - "ለተጨማሪ መረጃ ወደ %s ይሂዱ።" - "ወደ ደመና ይሰቀላል" - "እርስዎ ሲፈቅዱ ወደ ደመና ይሰቀላል" - "ከማስታወቂያ አስነጋሪዎች ወይም ንግዶች ጋር ይጋራል" - "እርስዎ በግልፅ ሲፈቅዱ ከማስታወቂያ አስነጋሪዎች ወይም ንግዶች ጋር ይጋራል" - "ለገንዘብ ማግኛ ጥቅም ላይ ይውላል" - "እርስዎ በግልፅ ሲፈቅዱ ለገንዘብ ማስገኛ ሥራዎች ጥቅም ላይ ይውላል" - "ይቀመጥና ለዘላለም ይተነተናል" - "እርስዎ ለጠቀሱት ጊዜ ቆይታ ይቀመጣል እና ይተነተናል" - - %s ሳምንታት ይቀመጣል እና ይተነተናል - %s ሳምንታት ይቀመጣል እና ይተነተናል - - "የመተግበሪያው ገንቢ መተግበሪያው እንዴት የእርስዎን ውሂብ እንደሚጠቀም አልጠቀሰም።" "መተግበሪያው በጥቅም ላይ እያለ ብቻ" "ምንም ፈቃዶች አልተፈቀዱም" "ምንም ፈቃዶች አልተከለከሉም" @@ -205,10 +184,18 @@ "የሙዚቃ መተግበሪያ" "የማዕከለ ሥዕላት መተግበሪያ" "የመኪና ሁነታ የስልክ መተግበሪያ" - "የወኪል ጥሪ ማድረጊያ መተግበሪያ" + + "የጥሪ ማጣሪያ መተግበሪያ" "የጥሪ አጋር መተግበሪያ" - - + "የእገዛ መተግበሪያ" + "የመኪና መጠበቂያ መተግበሪያ" "ማስታወሻ፦ የእርስዎን መሣሪያ ዳግም ካስጀምሩ እና ማያ ገጽ መቆለፊያው እንዲቀናበር ካደረጉ፣ ይህ መተግበሪያ የእርስዎን መሣሪያ ዳግም እስከሚከፍቱ ድረስ መጀመር አይችልም።" + "ሳንካ ማረሚያ ውሂብን አጋራ" + "ዝርዝር የሳንካ ማረሚያ መረጃ ይጋራ?" + "%1$s የሳንካ ማረሚያ መረጃን መስቀል ይፈልጋል።" + "ሳንካ ማረሚያ ውሂብን አጋራ" + "%1$s የሳንካ ሪፖርት ከዚህ መሣሪያ በ%2$s ላይ በ%3$s የተወሰደ የሳንካ ሪፖርትን ለመስቀል እየጠየቀ ነው። የሳንካ ሪፖርቶች ስለ የእርስዎ መሣሪያ ወይም በመተግበሪያዎች የተመዘገበ ለምሳሌ እንደ የተጠቃሚ ስሞች፣ የመገኛ አካባቢ ውሂብ፣ የመሣሪያ ለይቶ ማወቂያዎች እና የአውታረ መረብ መረጃን ያካትታል። ይህን መረጃ ከሚያምኗቸው ሰዎች እና መተግበሪያዎች ጋር ብቻ የሳንካ ሪፖርቶችን ያጋሩ። የሳንካ ሪፖርትን %4$s እንዲሰቅል ይፈቀድ?" + "ፍቀድ" + "ከልክል" diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml index f02406904..4ec22ab03 100644 --- a/res/values-ar/strings.xml +++ b/res/values-ar/strings.xml @@ -4,9 +4,9 @@ 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. @@ -118,17 +118,14 @@ "أعلى استخدام للأذونات في آخر 15 دقيقة" "الأذونات الأكثر استخدامًا خلال الدقيقة الماضية" "التطبيقات" - - - - + "تمّت التصفية حسب: %1$s" + "إزالة الفلتر" "تصفية بحسب" "تصفية بحسب الأذونات" "معظم الأذونات" "معظم مرّات الدخول" "آخر دخول" - - + "إعادة تحميل" "استخدام أذونات التطبيق" "استخدام الإذن: %1$s مرّة إجمالي المدّة: %2$s. آخر استخدام قبل %3$s." "استخدام الإذن: %1$s مرّة آخر استخدام قبل %2$s." @@ -141,11 +138,9 @@ "قبل %3$s، استخدَم تطبيق %1$s إذن %2$s الذي منحته." "لم يحصل تطبيق %1$s على إذن %2$s." "عرض تفاصيل استخدام الأذونات" - - + "آخر إذن وصول: %1$s" "التطبيقات أو الأذونات المسموح بها" - - + "السماح فقط أثناء الاستخدام" "التطبيقات أو الأذونات المرفوضة" "الاطّلاع على الاستخدام التفصيلي" @@ -185,26 +180,6 @@ "تذكيرات الأذونات" "يستخدِم التطبيق %s موقعك الجغرافي." "يمكن لهذا التطبيق دائمًا الوصول إلى بيانات موقعك الجغرافي. انقر لتغيير ذلك." - "يشير مطوّر التطبيق إلى احتمالية إجراء ما يلي بشأن البيانات:" - "إذا لم تعجبك طريقة استخدام مطوّر هذا التطبيق لبياناتك، يمكنك رفض الإذن." - "انتقِل إلى تطبيق %s للحصول على المزيد من المعلومات." - "يتم تحميل البيانات إلى السحابة الإلكترونية." - "يتم تحميل البيانات إلى السحابة الإلكترونية عند السماح بذلك بوضوح." - "تتم مشاركة البيانات مع المعلنين أو الأنشطة التجارية." - "تتم مشاركة البيانات مع المعلنين أو الأنشطة التجارية عند السماح بذلك بوضوح." - "يتم استخدام البيانات لتحقيق الربح المادي." - "يتم استخدام الإذن لتحقيق ربح مادي عند السماح بذلك بوضوح." - "يتم تحليل البيانات وحفظها إلى الأبد." - "يتم تحليل البيانات وحفظها للمدة التي تحدّدها." - - يتم تحليل البيانات وحفظها لمدة %s أسبوع.​ - يتم تحليل البيانات وحفظها لمدة أسبوعين (%s). - يتم تحليل البيانات وحفظها لمدة %s أسابيع. - يتم تحليل البيانات وحفظها لمدة %s أسبوعًا. - يتم تحليل البيانات وحفظها لمدة %s أسبوع.​ - يتم تحليل البيانات وحفظها لمدة أسبوع واحد. - - "لم يحدّد المطوّر طريقة استخدام التطبيق للبيانات." "أثناء استخدام التطبيق فقط" "لم يتم منح أي أذونات." "لم يتم رفض أي أذونات." @@ -229,10 +204,18 @@ "تطبيق الموسيقى" "تطبيق المعرض" "تطبيق الهاتف في وضع السيارة" - "تطبيق الاتصال بالخدام الوكيل" + + "تطبيق فحص المكالمات" "تطبيق مصاحب للمكالمات" - - + "تطبيق المساعد" + "‏تطبيق Car Projection" "ملاحظة: في حال إعادة تشغيل جهازك وضبط قفل شاشة، لا يمكن بدء هذا التطبيق إلى أن تفتح جهازك." + "مشاركة بيانات تصحيح الأخطاء" + "هل تريد مشاركة بيانات تصحيح الأخطاء التفصيلية؟" + "يريد تطبيق %1$s تحميل معلومات تصحيح الأخطاء." + "مشاركة بيانات تصحيح الأخطاء" + "يطلب تطبيق %1$s تحميل تقرير خطأ من هذا الجهاز تم تسجيله بتاريخ %2$s في %3$s. وتشمل تقارير الأخطاء المعلومات الشخصية حول جهازك أو المعلومات التي سجلتها التطبيقات، مثل أسماء المستخدمين وبيانات الموقع الجغرافي ومعرّفات الأجهزة ومعلومات الشبكة. ويجب عدم مشاركة تقارير الأخطاء إلا مع المستخدمين والتطبيقات التي تثق بمشاركة هذه المعلومات معها. هل تريد السماح لتطبيق %4$s بتحميل تقرير خطأ؟" + "سماح" + "رفض" diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml index bdecf7510..d48866e43 100644 --- a/res/values-as/strings.xml +++ b/res/values-as/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "যোৱা ১৫ মিনিটত আটাইতকৈ বেছি অনুমতিৰ ব্যৱহাৰ" "যোৱা ১ মিনিটত আটাইতকৈ বেছিকৈ বিচৰা অনুমতি" "এপ্" - - - - + "এই অনুসৰি ফিল্টাৰ কৰা: %1$s" + "ফিল্টাৰ আঁতৰাওক" "এই অনুসৰি ফিল্টাৰ কৰক" "অনুমতি অনুসৰি ফিল্টাৰ কৰক" "আটাইতকৈ বেছি অনুমতি" "আটাইতকৈ বেছি এক্সেছ" "শেহতীয়া" - - + "ৰিফ্ৰে’শ্ব কৰক" "এপৰ অনুমতিৰ ব্যৱহাৰ" "এক্সেছ কৰা হৈছে: %1$s বাৰ। মুঠ সময়: %2$s। অন্তিমবাৰ %3$s আগত ব্যৱহাৰ কৰা হৈছিল।" "এক্সেছ কৰা হৈছে: %1$s বাৰ। অন্তিমবাৰ %2$s আগত ব্যৱহাৰ কৰা হৈছিল।" @@ -137,11 +134,9 @@ "%1$sএ আপোনাৰ %2$s%3$s পূর্বে এক্সেছ পাইছিল।" "%1$sএ আপোনাৰ %2$s এক্সেছ কৰা নাই।" "অনুমতিৰ ব্যৱহাৰৰ সবিশেষ চাওক" - - + "অন্তিমবাৰ এক্সেছ কৰা হৈছিল: %1$s" "অনুমতি দিয়া হৈছে" - - + "কেৱল ব্যৱহাৰ হৈ থকা সময়ত অনুমতি দিয়া হয়" "অস্বীকাৰ কৰা হৈছে" "ব্যৱহাৰৰ সবিশেষ তথ্য চাওক" @@ -165,22 +160,6 @@ "অনুমতি বিষয়ক ৰিমাইণ্ডাৰ" "%sএ আপোনাৰ অৱস্থান ব্যৱহাৰ কৰি আছে" "এই এপটোৱে সদায় আপোনাৰ অৱস্থান এক্সেছ কৰিব পাৰে। সলনি কৰিবলৈ টিপক।" - "এপ্ বিকাশকৰ্তাৰ মতে আপোনাৰ ডেটা:" - "আপুনি যদি এই এপ্ বিকাশকৰ্তাই যেনেকৈ আপোনাৰ ডেটা ব্যৱহাৰ কৰিছে সেই কথা ভাল পোৱা নাই, তেন্তে আপুনি অনুমতিটো অস্বীকাৰ কৰিব পাৰে।" - "অধিক তথ্যৰ বাবে %sলৈ যাওক।" - "ক্লাউডত আপল’ড কৰা হয়" - "আপুনি স্পষ্টভাৱে অনুমতি দিলে ক্লাউডত আপল’ড কৰা হয়" - "বিজ্ঞাপনদাতা বা ব্যৱসায় প্ৰতিষ্ঠানৰ সৈতে শ্বেয়াৰ কৰা হয়" - "আপুনি যেতিয়া স্পষ্টভাৱে অনুমতি দিয়ে তেতিয়া বিজ্ঞাপনদাতা বা ব্যৱসায় প্ৰতিষ্ঠানৰ সৈতে শ্বেয়াৰ কৰা হয়" - "মুদ্ৰাকৰণৰ বাবে ব্যৱহাৰ কৰা হয়" - "আপুনি স্পষ্টভাৱে অনুমতি দিলে মুদ্ৰাকৰণত ব্যৱহাৰ কৰা হয়" - "চিৰকালৰ কাৰণে ছেভ কৰি ৰখা হয় আৰু বিশ্লেষণ কৰা হয়" - "আপুনি নিৰ্দিষ্ট কৰি দিয়া এক সময়সীমা পৰ্যন্ত ছেভ কৰি ৰখা হয় আৰু বিশ্লেষণ কৰা হয়" - - %s সপ্তাহ পৰ্যন্ত ছেভ কৰি ৰখা হয় আৰু বিশ্লেষণ কৰা হয় - %s সপ্তাহ পৰ্যন্ত ছেভ কৰি ৰখা হয় আৰু বিশ্লেষণ কৰা হয় - - "আপোনাৰ ডেটা এপটোৱে কেনেকৈ ব্যৱহাৰ কৰে সেই কথা এপটোৰ বিকাশকৰ্তাই উল্লেখ কৰা নাই।" "কেৱল এপটো ব্যৱহাৰ হৈ থকা সময়ত" "কোনো অনুমতি দিয়া নাই" "কোনো অনুমতি প্ৰত্যাখ্যান কৰা নাই" @@ -205,10 +184,18 @@ "Music এপ্‌" "Gallery এপ্" "গাড়ী ম’ড ফ’ন এপ্" - "প্ৰক্সি কল কৰা এপ্" + + "কল স্ক্ৰীণ কৰা এপ্" "কল সহযোগী এপ্" - - + "সহায়ক এপ্" + "গাড়ীৰ প্ৰজেকশ্বন এপ্‌" "টোকা: যদি আপুনি আপোনাৰ ডিভাইচটো ৰিষ্টাৰ্ট কৰে আৰু আপোনাৰ এটা স্ক্ৰীণ লক ছেট কৰি থোৱা আছে, তেন্তে এই এপটো আপুনি ডিভাইচটো আনলক নকৰালৈকে আৰম্ভ নহ’ব।" + "ডিবাগ ডেটা শ্বেয়াৰ কৰক" + "ডিবাগৰ সবিশেষ ডেটা শ্বেয়াৰ কৰিবনে?" + "%1$sএ ডিবাগ তথ্য আপল’ড কৰিব বিচাৰিছে।" + "ডিবাগ ডেটা শ্বেয়াৰ কৰক" + "%1$sএ এই ডিভাইচটোৰ %2$s তাৰিখে %3$sত সংগ্ৰহ কৰা এটা বাগ ৰিপ’ৰ্ট আপল’ড কৰাৰ অনুমতি বিচাৰিছে। সেই বাগ ৰিপ’ৰ্টটোত আপোনাৰ ডিভাইচটোৰ বিষয়ে ব্যক্তিগত তথ্য বা এপে লগ কৰা তথ্য, যেনে ব্যৱহাৰকাৰীৰ নাম, অৱস্থান ডেটা, ডিভাইচ পৰিচায়ক আৰু নেটৱৰ্ক সম্পৰ্কীয় তথ্য ইত্যাদি অন্তৰ্ভুক্ত থাকিব। এইখিনি তথ্যৰ ক্ষেত্ৰত কেৱল আপুনি বিশ্বাস কৰা ব্যক্তি বা এপৰ সৈতেহে বাগ ৰিপ’ৰ্ট শ্বেয়াৰ কৰক। %4$sক বাগ ৰিপ’ৰ্ট আপল’ড কৰাৰ অনুমতি দিবনে?" + "অনুমতি দিয়ক" + "অস্বীকাৰ কৰক" diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml index 85c3c0f28..3f24d8559 100644 --- a/res/values-az/strings.xml +++ b/res/values-az/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "Son 15 dəqiqədə ən çox işlənən icazə istifadəsi" "Son 1 dəqiqədə ən çox işlənən icazə istifadəsi" "Tətbiqlər" - - - - + "Filtrlədi: %1$s" + "Filtri silin" "Filtrləyin:" "İcazələr üzrə filtrləyin" "Verilən icazələrin sayı" "Edilən girişlərin sayı" "Ən son" - - + "Yeniləyin" "Tətbiq icazələri istifadəsi" "Giriş: %1$s dəfə. Yekun müddət: %2$s. Son istifadə %3$s əvvəl." "Giriş: %1$s dəfə. Son istifadə %2$s əvvəl." @@ -137,11 +134,9 @@ "%1$s %2$s adlı məkana %3$s əvvəl daxil oldu." "%1$s üçün %2$s icazəsi əlçatan deyil." "İcazələrin istifadəsi ilə bağlı ətraflı məlumata baxın" - - + "Son giriş: %1$s" "İcazə verilib" - - + "Yalnız istifadədə olarkən icazə verildi" "Ləğv edildi" "İstifadə haqqında ətraflı məlumat" @@ -165,22 +160,6 @@ "İcazə xatırladıcıları" "%s məkandan istifadə edir" "Bu tətbiq daima məkana daxil ola bilər. Dəyişmək üçün klikləyin." - "Tətbiq developerinin fikrincə datanız:" - "Əgər bu tətbiq developerinin datadan istifadə qaydasını bəyənmirsinizsə, icazəni ləğv edə bilərsiniz." - "Ətraflı məlumat üçün %s tətbiqinə daxil olun." - "Buluda yükləndi" - "İcazə verdiyiniz zaman buluda yükləndi" - "Reklamçılar və ya bizneslərlə paylaşıldı" - "İcazə verdiyiniz zaman ya reklamçılar, ya da bizneslərlə paylaşıldı" - "Monetizasiya üçün istifadə edildi" - "İcazə verdiyiniz zaman monetizasiya üçün istifadə edildi" - "Həmişəlik yadda saxlandı və təhlil edildi" - "Müəyyən etdiyiniz vaxt ərzində yadda saxlandı və təhlil edildi" - - %s həftəlik yadda saxlandı və təhlil edildi - 1 həftəlik yadda saxlandı və təhlil edildi - - "Tətbiq developeri tətbiqin datadan necə istifadə etdiyini müəyyən edə bilmədi." "Yalnız tətbiqin istifadəsi zamanı" "İcazə verilmədi" "İcazə verilib" @@ -205,10 +184,18 @@ "Musiqi tətbiqi" "Qalereya tətbiqi" "Avtomobil rejimi olan telefon" - "Proksi zəng tətbiqi" + + "Ekran zəngi tətbiqi" "Zəng kompanyon tətbiqi" - - + "Köməkçi tətbiq" + "Car Projection tətbiqi" "Qeyd: Cihazı yenidən başlatmısınızsa və cihazda ekran kilidi varsa, kilidi açmamış tətbiq başlaya bilməz." + "Sazlama Datasını Paylaşın" + "Ətraflı sazlama datası paylaşılsın?" + "%1$s sazlama məlumatını yükləmək istəyir." + "Sazlama Datasını Paylaşın" + "%1$s bu cihazdan %2$s, %3$s tarixində götürülmüş baq hesabatını yükləmək istəyir. Baq hesabatlarına istifadəçi adları, məkan datası, cihaz identifikatorları və şəbəkə məlumatı kimi cihaz və ya tətbiqlər haqqında məxfi məlumat daxildir. Baq hesabatlarını yalnız güvəndiyiniz şəxs və tətbiqlərlə paylaşın. %4$s tətbiqinə baq hesabatını yükləməyə icazə verilsin?" + "İcazə verin" + "Rədd edin" diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml index a244aa849..d82912ded 100644 --- a/res/values-b+sr+Latn/strings.xml +++ b/res/values-b+sr+Latn/strings.xml @@ -4,9 +4,9 @@ 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. @@ -115,17 +115,14 @@ "Najviše korišćene dozvole u poslednjih 24 minuta" "Najviše korišćene dozvole u poslednjem minutu" "Aplikacije" - - - - + "Filtrirano prema: %1$s" + "Ukloni filter" "Filtriraj prema" "Filtriraj prema dozvolama" "Najviše dozvola" "Najveći broj pristupa" "Nedavno" - - + "Osveži" "Korišćenje dozvola za aplik." "Pristup: %1$s put(a). Ukupno trajanje: %2$s. Poslednji put korišćena pre %3$s." "Pristup: %1$s put(a). Poslednji put korišćena pre %2$s." @@ -138,11 +135,9 @@ "Aplikacija %1$s je pristupila dozvoli %2$s pre %3$s." "Aplikacija %1$s nije pristupila dozvoli %2$s." "Pregledajte detaljne dozvole za korišćenje" - - + "Poslednji pristup: %1$s" "Dozvoljeno" - - + "Dozvoljeno samo dok se aplikacija koristi" "Odbijeno" "Pogledajte detaljnu upotrebu" @@ -170,23 +165,6 @@ "Podsetnici za dozvole" "%s koristi vašu lokaciju" "Ova aplikacija može uvek da pristupa lokaciji. Dodirnite da biste to promenili." - "Programer aplikacije kaže da podaci mogu:" - "Ako vam se ne sviđa kako ovaj programer aplikacije koristi podatke, možete da povučete dozvolu." - "Idite u aplikaciju %s da biste dobili više informacija." - "da se otpremaju u klaud" - "da se otpremaju u klaud kada to izričito dozvolite" - "da se dele sa oglašavačima ili preduzećima" - "da se dele sa oglašavačima ili preduzećima kada to izričito dozvolite" - "da se koriste za monetizaciju" - "da se koriste za monetizaciju kada to izričito dozvolite" - "da se čuvaju i analiziraju zauvek" - "da se čuvaju i analiziraju u periodu koji vi navedete" - - da se čuvaju i analiziraju %s nedelju - da se čuvaju i analiziraju %s nedelje - da se čuvaju i analiziraju %s nedelja - - "Programer aplikacije nije naveo kako aplikacija koristi podatke." "Samo dok se aplikacija koristi" "Dozvole nisu odobrene" "Nijedna dozvola nije odbijena" @@ -211,10 +189,18 @@ "Aplikacija Muzika" "Aplikacija Galerija" "Aplikacija za telefon sa režimom rada u automobilu" - "Aplikacija za proksi pozive" + + "Aplik. za uprav. dolaz. poziv." "Pozivanje prateće aplikacije" - - + "Aplikacija za pomoć" + "Aplik. Projekcija u automobilu" "Napomena: Ako restartujete uređaj i podesili ste zaključavanje ekrana, ova aplikacija ne može da se pokrene dok ne otključate uređaj." + "Deljenje podataka o otklanjanju grešaka" + "Delite detaljne podatke za otklanjanje grešaka?" + "%1$s želi da otpremi informacije za otklanjanje grešaka." + "Deljenje podataka o otklanjanju grešaka" + "%1$s traži da otpremi izveštaj o greškama sa ovog uređaja koji je napravljen %2$s u %3$s. Izveštaji o greškama obuhvataju lične podatke o uređaju ili podatke koje su evidentirale aplikacije, na primer, korisnička imena, podatke o lokaciji, identifikatore uređaja i informacije o mreži. Delite izveštaje o greškama samo sa ljudima i aplikacijama kojima možete da poverite te informacije. Želite li da dozvolite da %4$s otpremi izveštaj o grešci?" + "Dozvoli" + "Odbij" diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml index ce1072534..15e4ab51b 100644 --- a/res/values-be/strings.xml +++ b/res/values-be/strings.xml @@ -4,9 +4,9 @@ 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. @@ -116,17 +116,14 @@ "Самыя частыя дазволы за апошнія 15 хвілін" "Найчасцей выкарыстаныя дазволы за апошнюю хвіліну" "Праграмы" - - - - + "Параметр фільтравання: %1$s" + "Выдаліць фільтр" "Параметр фільтравання" "Фільтраваць па дазволах" "Найбольшая колькасць дазволаў" "Найбольшая колькасць доступаў" "Нядаўнія" - - + "Абнавіць" "Выкарыстанне дазволаў праграмы" "Доступ: колькасць разоў – %1$s. Агульная працягласць: %2$s. Апошняе выкарыстанне – %3$s таму назад." "Доступ: колькасць разоў – %1$s. Апошняе выкарыстанне – %2$s таму назад." @@ -139,11 +136,9 @@ "Праграма \"%1$s\" атрымала доступ да дазволу \"%2$s\" %3$s таму назад." "Праграма \"%1$s\" не атрымала доступу да функцыі \"%2$s\"." "Прагледзець звесткі пра выкарыстанне дазволаў" - - + "Апошні доступ: %1$s" "Дазволеныя" - - + "Дазволена толькі падчас карыстання" "Адмоўленыя" "Паказаць падрабязнасці выкарыстання" @@ -175,24 +170,6 @@ "Напаміны пра дазволы" "Праграма \"%s\" выкарыстоўвае даныя пра ваша месцазнаходжанне" "Гэта праграма заўсёды можа атрымаць доступ да даных пра ваша месцазнаходжанне. Націсніце, каб змяніць." - "Паводле звестак распрацоўшчыка вашы даныя могуць:" - "Калі вам не падабаецца, як распрацоўшчык праграмы выкарыстоўвае вашы даныя, вы можаце адмовіць яму ў дазволе." - "Каб атрымаць дадатковую інфармацыю, перайдзіце ў праграму \"%s\"." - "Запампоўвацца ў воблака" - "Запампоўвацца ў воблака з вашага яўнага дазволу" - "Абагульвацца з рэкламадаўцамі і кампаніямі" - "Абагульвацца з рэкламадаўцамі і кампаніямі з вашага яўнага дазволу" - "Выкарыстоўваюцца для манетызацыі" - "Выкарыстоўвацца для манетызацыі з вашага яўнага дазволу" - "Заўсёды захоўвацца і аналізавацца" - "Захоўваюцца і аналізуюцца на працягу вызначанага перыяду" - - Захоўвацца і аналізавацца на працягу %s тыдня​ - Захоўвацца і аналізавацца на працягу %s тыдняў - Захоўвацца і аналізавацца на працягу %s тыдняў - Захоўвацца і аналізавацца на працягу %s тыдня​ - - "Распрацоўшчык праграмы не вызначыў, як яна выкарыстоўвае даныя." "Толькі ў актыўным рэжыме праграмы" "Няма дазволаў" "Дазволы не адхілены" @@ -217,10 +194,18 @@ "Праграма \"Музыка\"" "Праграма \"Галерэя\"" "Праграма рэжыму \"У аўтамабілі\"" - "Праграма для проксі-выклікаў" + + "Праграма фільтравання выклікаў" "Спадарожная праграма выклікаў" - - + "Праграма-памочнік" + "Праграма трансляцыі на экран" "Заўвага. Калі перазапусціць прыладу з наладжанай блакіроўкай экрана, праграма не запусціцца, пакуль вы не разблакіруеце прыладу." + "Абагульванне даных адладкі" + "Абагуліць падрабязнасці адладкі?" + "Праграма \"%1$s\" спрабуе запампаваць звесткі пра адладку." + "Абагульванне даных адладкі" + "Праграма \"%1$s\" запытвае запампоўку справаздачы пра памылкі з гэтай прылады ад %2$s у %3$s. Справаздача пра памылкі ўключае персанальную інфармацыю пра вашу прыладу ці зарэгістраваныя праграмы, напрыклад імёны карыстальнікаў, звесткі пра месцазнаходжанне, ідэнтыфікатары прылады і даныя пра сетку. Абагульвайце справаздачы пра памылкі толькі з людзьмі і праграмамі, якім давяраеце. Дазволіць праграме \"%4$s\" запампаваць справаздачу пра памылкі?" + "Дазволіць" + "Адмовіць" diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml index f2da39a19..ea973e385 100644 --- a/res/values-bg/strings.xml +++ b/res/values-bg/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "Най-използвани разрешения през последните 15 мин" "Най-използваните разрешения през последната минута" "Приложения" - - - - + "Филтрирано по: %1$s" + "Премахване на филтъра" "Филтриране по" "Филтриране по разрешения" "Най-много разрешения" "Най-много осъществ. на достъп" "Скорошни" - - + "Опресняване" "Използване на разрешенията" "Достъп: %1$s пъти. Обща продължителност: %2$s. Последно използване преди %3$s." "Достъп: %1$s пъти. Последно използване преди %2$s." @@ -137,11 +134,9 @@ "%1$s осъществи достъп до %2$s ви преди %3$s." "Приложението %1$s не е осъществило достъп до %2$s." "Преглед на подробности за използването на разрешенията" - - + "Последен достъп: %1$s" "Разрешено" - - + "Разрешено само при използване" "Отказано" "Преглед на подробната употреба" @@ -165,22 +160,6 @@ "Напомняния за разрешения" "%s използва местоположението ви" "Приложението винаги има достъп до местоположението ви. Докоснете, за да промените това." - "Програмистът на приложението посочва, че данните ви може да:" - "Ако не харесвате как програмистът на това приложение използва данните ви, можете да откажете разрешението." - "Отворете %s за още информация." - "Се качват в облака." - "Се качват в облака, когато изрично го разрешите." - "Се споделят с рекламодатели или бизнеси." - "Се споделят с рекламодатели или бизнеси, когато изрично го разрешите." - "Се използват за осигуряване на приходи." - "Се използват за осигуряване на приходи, когато изрично го разрешите." - "Се запазват и анализират завинаги." - "Се запазват и анализират за посочена от вас продължителност." - - Се запазват и анализират за %s седмици. - Се запазват и анализират за 1 седмица. - - "Програмистът на приложението не е посочил как то използва данните ви." "Само докато приложението се използва" "Няма позволени разрешения" "Няма отказани разрешения" @@ -205,10 +184,18 @@ "Приложение за музика" "Приложение за галерия" "Прил. за телефон в моторежим" - "Прил. за обажд. през прокси сървър" + + "Прил. за отсяване на обажд." "Придружаващо прил. за обажд." - - + "Помощно приложение" + "Прожектиране в автомобила" "Забележка: Ако рестартирате устройството си и сте задали опция за заключване на екрана, това приложение не може да стартира, докато не отключите устройството си." + "Споделяне на данните за отстраняване на грешки" + "Споделяне на подробни данни за отстран. на грешки?" + "%1$s иска да качи информация за отстраняване на грешки." + "Споделяне на данните за отстраняване на грешки" + "%1$s иска да качи сигнал за програмна грешка от това устройство, създаден на %2$s в %3$s. Сигналите за програмни грешки включват лична информация за устройството ви или регистрирана от приложенията, като например потребителски имена, данни за местоположението, идентификатори на устройството и информация за мрежата. Споделяйте сигналите за програмни грешки само с хора и приложения, на които бихте доверили тази информация. Да се разреши ли на %4$s да качи сигнал за програмна грешка?" + "Разрешаване" + "Отказ" diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml index a97f738a8..1bc1c7262 100644 --- a/res/values-bn/strings.xml +++ b/res/values-bn/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "১৫ মিনিটে আগে সবচেয়ে বেশি অনুমতির ব্যবহার" "গত ১ মিনিটে সবচেয়ে বেশি অনুমতির ব্যবহার" "অ্যাপ" - - - - + "এই অনুযায়ী ফিল্টার করা হয়েছে: %1$s" + "ফিল্টার সরান" "এই অনুযায়ী ফিল্টার করুন" "অনুমতির মাধ্যমে ফিল্টার করুন" "বেশি ব্যবহার করা অনুমতি" "সবচেয়ে বেশি অ্যাক্সেস করা" "সাম্প্রতিক" - - + "রিফ্রেশ করুন" "অ্যাপের অনুমতির ব্যবহার" "অ্যাক্সেস: %1$s বার। মোট সময়সীমা: %2$s%3$sআগে শেষবার ব্যবহার করা হয়েছে।" "অ্যাক্সেস: %1$s বার। %2$s আগে শেষবার ব্যবহার করা হয়েছে।" @@ -137,11 +134,9 @@ "আপনার %2$s %3$s আগে %1$s অ্যাক্সেস করা হয়েছে।" "%1$s আপনার %2$s অ্যাক্সেস করতে পারেনি।" "বিস্তারিত অনুমতির ব্যবহার দেখুন" - - + "শেষবার অ্যাক্সেস করা হয়েছে: %1$s" "অনুমোদিত" - - + "শুধুমাত্র ব্যবহার করার সময় অনুমোদিত" "প্রত্যাখ্যান করা হয়েছে" "বিশদে ব্যবহারের তথ্য দেখুন" @@ -165,22 +160,6 @@ "অনুমতির রিমাইন্ডার" "%s আপনার লোকেশনের ডেটা ব্যবহার করছে" "এই অ্যাপটি যেকোনও সময় আপনার লোকেশনের ডেটা অ্যাক্সেস করতে পারে। পরিবর্তন করতে ট্যাপ করুন।" - "অ্যাপ ডেভেলপার বলেছেন আপনার ডেটা হয়ত:" - "অ্যাপ ডেভেলপার যেভাবে আপনার ডেটা ব্যবহার করছে তা আপনার পছন্দ না হলে আপনি অনুমতি নাও দিতে পারেন।" - "আরও তথ্য পেতে %s অ্যাপে যান।" - "ক্লাউডে আপলোড করা হয়েছে" - "নির্দিষ্ট অনুমতি দেওয়ায় ক্লাউডে আপলোড করা হয়েছে" - "বিজ্ঞাপনদাতা বা ব্যবসার সঙ্গে শেয়ার করা হয়েছে" - "নির্দিষ্ট অনুমতি দেওয়া হলে বিজ্ঞাপনদাতা বা ব্যবসার সঙ্গে শেয়ার করা হবে" - "উপার্জনের জন্য ব্যবহার করা হয়" - "নির্দিষ্ট অনুমতি দিলে তবেই উপার্জনের জন্য ব্যবহার হয়" - "বিশ্লেষণ করে চিরদিনের জন্য সেভ করা হয়েছে" - "আপনার নির্দিষ্ট করা সময়ের জন্য বিশ্লেষণ করে সেভ করা হয়েছে" - - %s সপ্তাহের জন্য বিশ্লেষণ করে সেভ করা হয়েছে - %s সপ্তাহের জন্য বিশ্লেষণ করে সেভ করা হয়েছে - - "অ্যাপ আপনার ডেটা কীভাবে ব্যবহার করবে তা অ্যাপ ডেভেলপার নির্দিষ্ট করে দেয়নি।" "শুধুমাত্র অ্যাপ ব্যবহারের সময়" "কোনও অনুমতি নেই" "কোনও অনুমতি প্রত্যাখান করা হয়নি" @@ -205,10 +184,18 @@ "মিউজিক অ্যাপ" "গ্যালারি অ্যাপ" "গাড়ির মোডে ফোন অ্যাপ" - "প্রক্সি কলিং অ্যাপ" + + "কল স্ক্রিনিং অ্যাপ" "কল কম্প্যানিয়ন অ্যাপ" - - + "সহায়তা অ্যাপ" + "গাড়ির প্রোজেকশন অ্যাপ" "দ্রষ্টব্য: আপনি যদি নিজের ডিভাইস রিস্টার্ট করেন এবং স্ক্রিন লক সেট করা থাকে, তাহলে আপনার ডিভাইস আনলক না করা পর্যন্ত আপনি এই অ্যাপটি চালু করতে পারবেন না।" + "ডিবাগিং ডেটা শেয়ার করুন" + "ডিবাগিংয়ের বিস্তারিত ডেটা শেয়ার করতে চান?" + "%1$s ডিবাগিংয়ের তথ্য আপলোড করতে চায়।" + "ডিবাগিং ডেটা শেয়ার করুন" + "এই ডিভাইস থেকে %2$s তারিখে %3$s-এ নেওয়া একটি সমস্যার রিপোর্ট %1$s আপলোড করতে চাইছে। ইউজার নেম, লোকেশন ডেটা, ডিভাইসের শনাক্তকারী ও নেটওয়ার্কের তথ্যের মতো আপনার ডিভাইস ও লগ-ইন করা অ্যাপের ব্যাপারে ব্যক্তিগত তথ্য সমস্যার রিপোর্টে অন্তর্ভুক্ত থাকে। যেসব লোকজন বা অ্যাপকে আপনি এই তথ্য জানানোর ব্যাপারে বিশ্বাস করতে পারেন শুধুমাত্র তাদের সাথেই সমস্যার রিপোর্ট শেয়ার করুন। একটি সমস্যার রিপোর্ট আপলোড করতে %4$sকে অনুমতি দিতে চান?" + "অনুমতি দিন" + "অনুমতি দেবেন না" diff --git a/res/values-bs-television/strings.xml b/res/values-bs-television/strings.xml index 0ba780b65..b83e73b77 100644 --- a/res/values-bs-television/strings.xml +++ b/res/values-bs-television/strings.xml @@ -20,8 +20,8 @@ "Ovo možete kasnije promijeniti u odjeljku Postavke i Aplikacije" "%1$s/%2$s" "Prikaži sistemske aplikacije" - "Odobrenja za aplikacije" - "Odobrenja za aplikacije" + "Odobrenja za aplikaciju" + "Odobrenja za aplikaciju" "Odobrenja za: %1$s" "Dodatna odobrenja" "Odobrenja za: %1$s" diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml index ef8a6dc5b..59d49be62 100644 --- a/res/values-bs/strings.xml +++ b/res/values-bs/strings.xml @@ -4,9 +4,9 @@ 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. @@ -38,7 +38,7 @@ "Dozvoli svaki put" "Dozvoli samo kada se aplikacija koristi" "Aplikacije" - "Odobrenja za aplikacije" + "Odobrenja za aplikaciju" "Ne pitaj ponovo" "Nema odobrenja" "Dodatna odobrenja" @@ -115,17 +115,14 @@ "Najviše korištena odobrenja u posljednjih 15 min" "Najviše korištena odobrenja u posljednjoj minuti" "Aplikacije" - - - - + "Filtrirano po: %1$s" + "Ukloni filter" "Filtriraj po" "Filtriraj prema odobrenjima" "Najviše odobrenja" "Najviše pristupa" "Nedavno" - - + "Osvježi" "Korišt. dozvole za aplikacije" "Pristup: %1$s puta. Ukupno trajanje: %2$s. Zadnji put korištena prije %3$s." "Pristup: %1$s puta. Zadnji put korištena prije %2$s." @@ -138,11 +135,9 @@ "Aplikacija %1$s je pristupila odobrenju %2$s prije %3$s." "Aplikacija %1$s nije pristupila vašem odobrenju %2$s." "Vidi detaljno korištenje odobrenja" - - + "Posljednji pristup: %1$s" "Dozvoljeno" - - + "Dozvoljeno samo tokom upotrebe" "Odbijeno" "Pogledajte detalje o korištenju" @@ -170,23 +165,6 @@ "Podsjetnici odobrenja" "Aplikacija %s je koristila vašu lokaciju" "Ova aplikacija uvijek može pristupiti vašoj lokaciji. Dodirnite da promijenite." - "Programer aplikacije kaže da vaši podaci mogu biti:" - "Ako vam se ne sviđa način na koji programer aplikacije koristi vaše podatke, možete odbiti odobrenje." - "Otvorite aplikaciju %s za više informacija." - "otpremani u oblak" - "otpremani u oblak kada to vi izričito dozvolite" - "dijeljeni s oglašivačima ili preduzećima" - "dijeljeni s oglašivačima ili preduzećima kada to vi izričito dozvolite" - "korišteni za unovčavanje" - "korišteni za unovčavanje kada to vi izričito dozvolite" - "analizirani i sačuvani zauvijek" - "analizirani i sačuvani na vremenski period koji vi naznačite" - - analizirani i čuvani %s sedmicu - analizirani i čuvani %s sedmice - analizirani i čuvani %s sedmica - - "Programer aplikacije nije naznačio kako aplikacija koristi vaše podatke." "Samo kada se aplikacija koristi" "Nijedno odobrenje nije dato" "Nijedno odobrenje nije odbijeno" @@ -211,10 +189,18 @@ "Aplikacija za muziku" "Aplikacija galerije" "Apl. za način rada u automob." - "Aplikacija za proksi pozive" + + "Aplik. za filtriranje poziva" "Prateća aplikacija za pozive" - - + "Aplikacija za pomoć" + "Apl. za projekciju u automobilu" "Napomena: Ako ponovo pokrenete uređaj, a postavili ste zaključavanje ekrana, ova aplikacija se neće moći pokrenuti dok ne otključate uređaj." + "Dijeljenje podataka o otklanjanju grešaka" + "Dijeliti detaljne podatke o otklanjanju grešaka?" + "Aplikacija %1$s želi otpremiti informacije o otklanjanju grešaka." + "Dijeljenje podataka o otklanjanju grešaka" + "Aplikacija %1$s traži otpremanje izvještaja o greškama s ovog uređaja koji je izvršen dana %2$s u %3$s. Izvještaji o greškama uključuju lične informacije o vašem uređaju ili akreditivima za prijave u aplikacije, naprimjer korisnička imena, podatke o lokaciji, identifikatore uređaja i informacije o mreži. Izvještaje o greškama dijelite samo s osobama i aplikacijama kojim vjerujete. Dozvoliti aplikaciji %4$s da otpremi izvještaj o greškama?" + "Dozvoli" + "Odbij" diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml index b0ab75e33..64952e236 100644 --- a/res/values-ca/strings.xml +++ b/res/values-ca/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "Permisos més utilitzats durant els últims 15 minuts" "Permisos més utilitzats durant l\'últim minut" "Aplicacions" - - - - + "Filtrats per: %1$s" + "Suprimeix el filtre" "Filtra per" "Filtra per permisos" "Amb més permisos" "Amb més accessos" "Recents" - - + "Actualitza" "Ús de permisos de l\'aplicació" "Accés: %1$s vegades. Durada total: %2$s. Utilitzada per última vegada fa %3$s." "Accés: %1$s vegades. Utilitzada per última vegada fa %2$s." @@ -137,11 +134,9 @@ "%1$s va accedir fa %3$s a %2$s." "%1$s no ha accedit al permís %2$s." "Mostra dades detallades sobre l\'ús de permisos" - - + "Últim accés: %1$s" "Acceptats" - - + "Només es permeten mentre s\'utilitzen" "Denegats" "Mostra l\'ús detallat" @@ -165,22 +160,6 @@ "Recordatoris de permisos" "%s ha estat utilitzant la teva ubicació" "Aquesta aplicació pot accedir a la teva ubicació en qualsevol moment. Toca per canviar-ho." - "El desenvolupador de l\'aplicació diu que és possible que es faci el següent amb les teves dades:" - "Si no t\'agrada com fa servir les teves dades el desenvolupador de l\'aplicació, pots denegar el permís." - "Ves a %s per obtenir més informació." - "Es pengin al núvol" - "Es pengin al núvol quan ho permetis de manera explícita" - "Es comparteixin amb els anunciants o les empreses" - "Es comparteixin amb els anunciants o les empreses quan ho permetis de manera explícita" - "Es facin servir per obtenir ingressos" - "Es facin servir per obtenir ingressos quan ho permetis de manera explícita" - "Es desin i s\'analitzin sempre" - "Es desin i s\'analitzin durant el període que especifiquis" - - Es desin i s\'analitzin durant %s setmanes - Es desin i s\'analitzin durant 1 setmana - - "El desenvolupador de l\'aplicació no ha especificat com fa servir les teves dades l\'aplicació." "Només mentre s\'utilitza l\'aplicació" "No s\'ha concedit cap permís" "No s\'ha denegat cap permís" @@ -205,10 +184,18 @@ "Aplicació Música" "Aplicació Galeria" "Aplicació mode de cotxe" - "Aplicació de trucades de proxy" + + "Aplicació per filtrar trucades" "Aplicació complementària de trucades" - - + "Aplicació d\'assistència" + "Aplicació projecció del cotxe" "Nota: si reinicies el dispositiu i has definit un bloqueig de pantalla, l\'aplicació no s\'iniciarà fins que no desbloquegis el dispositiu." + "Comparteix les dades de depuració" + "Vols compartir els detalls de la depuració?" + "%1$s vol penjar informació de depuració." + "Comparteix les dades de depuració" + "%1$s sol·licita penjar un informe d\'errors des d\'aquest dispositiu generat el dia %2$s (%3$s). Els informes d\'errors inclouen informació personal sobre el dispositiu o informació registrada per les aplicacions, com ara noms d\'usuaris, dades de la ubicació, identificadors del dispositiu i informació de la xarxa. Comparteix informes d\'errors només amb persones i aplicacions de confiança. Vols permetre que %4$s pengi un informe d\'errors?" + "Permet" + "Denega" diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml index 6292e1b95..5f1e7ac0b 100644 --- a/res/values-cs/strings.xml +++ b/res/values-cs/strings.xml @@ -4,9 +4,9 @@ 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. @@ -116,17 +116,14 @@ "Nejpoužívanější oprávnění za posledních 15 minut" "Nejpoužívanější oprávnění za poslední 1 minutu" "Aplikace" - - - - + "Filtrováno podle: %1$s" + "Odstranit filtr" "Filtrovat podle" "Filtrovat podle oprávnění" "Nejvíce oprávnění" "Nejvíce použití" "Nedávné" - - + "Obnovit" "Využití oprávnění aplikace" "Přístup: %1$s×. Celkový čas: %2$s. Naposledy použito před %3$s." "Přístup: %1$s×. Naposledy použito před %2$s." @@ -139,11 +136,9 @@ "Aplikace %1$s získala před %3$s přístup k těmto údajům: %2$s." "Aplikace %1$s nezískala přístup k oprávnění %2$s." "Zobrazit podrobné využití oprávnění" - - + "Poslední přístup: %1$s" "Povoleno" - - + "Povoleno pouze během používání" "Zamítnuto" "Zobrazit podrobné údaje o využití" @@ -175,24 +170,6 @@ "Připomenutí o oprávněních" "Aplikace %s využívá vaši polohu" "Tato aplikace má neomezený přístup k poloze. Klepnutím to změníte." - "Vývojář aplikace informuje, že vaše data mohou být:" - "Pokud se vám nelíbí, jak vývojář této aplikace vaše data využívá, můžete oprávnění zamítnout." - "Další informace najdete v aplikaci %s." - "Nahrána do cloudu" - "Nahrána do cloudu, když to výslovně povolíte" - "Sdílena s inzerentem nebo firmou" - "Sdílena s inzerenty nebo firmami, když to výslovně povolíte" - "Používána k monetizaci" - "Používána k monetizaci, když to výslovně povolíte" - "Uložena a analyzována po neomezenou dobu" - "Uložena a analyzována po dobu, kterou určíte" - - Uložena a analyzována po dobu %s týdnů - Uložena a analyzována po dobu %s týdne - Uložena a analyzována po dobu %s týdnů - Uložena a analyzována po dobu jednoho týdne - - "Vývojář aplikace neurčil, jak aplikace využívá vaše data." "Jen během používání aplikace" "Nejsou povolena žádná oprávnění" "Nejsou zakázána žádná oprávnění" @@ -217,10 +194,18 @@ "Aplikace Hudba" "Aplikace Galerie" "Telefonování v autě" - "Zprostředkování hovorů" + + "Ohlašování jména volajícího" "Doprovod. aplikace na volání" - - + "Asistenční aplikace" + "Aplikace na promítání do auta" "Poznámka: Pokud restartujete zařízení a máte nastavený zámek obrazovky, tato aplikace se nespustí, dokud zařízení neodemknete." + "Sdílet data ladění" + "Sdílet podrobná data pro ladění?" + "Aplikace %1$s chce nahrát informace pro ladění." + "Sdílet data ladění" + "Aplikace %1$s chce nahrát zprávu o chybě tohoto zařízení, která byla pořízena %2$s v %3$s. Zprávy o chybě zahrnují osobní údaje o zařízení a údaje z aplikací, např. uživatelská jména, údaje o poloze, identifikátory zařízení a informace o sítích. Zprávy o chybách sdílejte jen s lidmi a aplikacemi, kterým důvěřujete. Chcete aplikaci %4$s povolit nahrát zprávu o chybě?" + "Povolit" + "Zamítnout" diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml index dfbf4d5e9..b272e6b46 100644 --- a/res/values-da/strings.xml +++ b/res/values-da/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "Mest anvendte tilladelser i de seneste 15 minutter" "Mest anvendte tilladelser det seneste minut" "Apps" - - - - + "Filtreret efter: %1$s" + "Fjern filter" "Filtrér efter" "Filtrér efter tilladelser" "Flest tilladelser" "Flest adgange" "Seneste" - - + "Opdater" "Brug af apptilladelser" "Adgang: %1$s gange. Samlet varighed: %2$s. Senest brugt for %3$s siden." "Adgang: %1$s gange. Senest brugt for %2$s siden." @@ -137,11 +134,9 @@ "%1$s anvendte din/dit %2$s for %3$s siden." "%1$s har ikke adgang til din %2$s." "Se detaljeret brug af tilladelser" - - + "Seneste adgang: %1$s" "Tilladt" - - + "Tillades kun, mens de er i brug" "Afvist" "Se detaljerede oplysninger om brug" @@ -165,22 +160,6 @@ "Påmindelser om tilladelse" "%s har anvendt din placering" "Denne app kan altid få adgang til din placering. Tryk for at ændre denne indstilling." - "Appudvikleren siger, at dine data kan:" - "Hvis du ikke kan lide den måde, som appudvikleren bruger dine data på, kan du afvise tilladelsen." - "Gå til %s for at få flere oplysninger." - "Uploades til skyen" - "Uploades til skyen, når du udtrykkeligt giver tilladelse" - "Deles med annoncører og virksomheder" - "Deles med annoncører og virksomheder, når du udtrykkeligt giver tilladelse" - "Bruges til indtægtsgenerering" - "Bruges til indtægtsgenerering, når du udtrykkeligt giver tilladelse" - "Gemmes og analyseres for evigt" - "Gemmes og analyseres i en tidsperiode, som du angiver" - - Gemmes og analyseres i %s uge - Gemmes og analyseres i %s uger - - "Appudvikleren har ikke angivet, hvordan appen bruger dine data." "Kun mens appen er i brug" "Der ikke givet nogen tilladelser" "Ingen tilladelser er blevet afvist" @@ -205,10 +184,18 @@ "Musikapp" "Galleriapp" "Telefonapp til biltilstand" - "App til proxy-kald" + + "App til opkaldsvalg" "Medfølgende opkaldsapp" - - + "Assistanceapp" + "Appen Bilprojicering" "Bemærk! Hvis du genstarter din enhed og har indstillet en skærmlås, kan denne app ikke starte, før du låser enheden op." + "Del fejlretningsdata" + "Vil du dele detaljerede fejlretningsdata?" + "%1$s vil gerne uploade fejretningsoplysninger." + "Del fejlretningsdata" + "%1$s anmoder om at uploade en fejlrapport fra denne enhed, som stammer fra %2$s kl. %3$s. Fejlrapporter indeholder personlige oplysninger om din enhed eller registreres af apps, f.eks. brugernavne, steddata, enheds-id\'er og netværksoplysninger. Oplysningerne i fejlrapporterne må kun deles med personer og apps, du har tillid til. Vil du give %4$s tilladelse til at uploade en fejlrapport?" + "Tillad" + "Afvis" diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index 0393be9c2..47c1f4b2c 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "Meiste Berechtigungsnutzungen (letzte 15 Minuten)" "Häufigste Berechtigungsnutzungen (letzte Minute)" "Apps" - - - - + "Gefiltert nach: %1$s" + "Filter entfernen" "Filtern nach" "Nach Berechtigungen filtern" "Meiste Berechtigungen" "Meiste Zugriffe" "Letzte" - - + "Aktualisieren" "Nutzung von App-Berechtigungen" "Zugriff: %1$s Mal. Gesamtdauer: %2$s. Zuletzt verwendet vor %3$s." "Zugriff: %1$s Mal. Zuletzt verwendet vor %2$s" @@ -137,11 +134,9 @@ "%1$s hat vor %3$s auf %2$s zugegriffen." "%1$s hat nicht auf %2$s zugegriffen." "Details zur Berechtigungsnutzung ansehen" - - + "Letzter Zugriff: %1$s" "Zulässig" - - + "Nur während der Verwendung erlaubt" "Abgelehnt" "Detaillierte Nutzungen ansehen" @@ -165,22 +160,6 @@ "Berechtigungserinnerungen" "%s hat deinen Standort verwendet" "Diese App kann immer auf deinen Standort zugreifen. Zum Ändern hier tippen." - "Laut des App-Entwicklers können deine Daten:" - "Wenn dir nicht gefällt, wie dieser App-Entwickler deine Daten verwendet, kannst du ihm die Berechtigung verweigern." - "Für weitere Informationen %s aufrufen." - "In die Cloud hochgeladen" - "In die Cloud hochgeladen, wenn du es ausdrücklich erlaubst" - "Für Werbetreibende und Unternehmen freigegeben" - "Für Werbetreibende und Unternehmen freigegeben, wenn du es ausdrücklich erlaubst" - "Zur Monetarisierung verwendet" - "Zur Monetarisierung verwendet, wenn du es ausdrücklich erlaubst" - "Für immer gespeichert und analysiert" - "Für eine von dir angegebene Dauer gespeichert und analysiert" - - Für %s Wochen gespeichert und analysiert - Für 1 Woche gespeichert und analysiert - - "Der App-Entwickler hat nicht angegeben, wie deine Daten in der App verwendet werden." "Nur während die App verwendet wird" "Keine Berechtigungen zugelassen" "Alle Berechtigungen zugelassen" @@ -205,10 +184,18 @@ "Musik App" "Galerie App" "Automodus-Telefon-App" - "Proxy-Anruf-App" + + "Call Screening-App" "Companion App für Anrufe" - - + "Assistent-App" + "App \"Übertragung an Auto\"" "Hinweis: Hinweis: Wenn du dein Gerät neu startest und eine Displaysperre aktiviert ist, wird diese App erst gestartet, wenn du dein Gerät entsperrst." + "Daten zur Fehlerbehebung teilen" + "Detaillierte Daten zur Fehlerbehebung teilen?" + "%1$s möchte Informationen zur Fehlerbehebung hochladen." + "Daten zur Fehlerbehebung teilen" + "%1$s möchte einen Fehlerbericht von diesem Gerät hochladen, der am %2$s um %3$s erstellt wurde. Fehlerberichte enthalten Informationen zu deinem Gerät, die du persönlich eingegeben hast oder die von Apps aufgezeichnet werden, z. B. Nutzernamen, Standortdaten, Geräte-IDs und Netzwerkinformationen. Teile Fehlerberichte nur mit Personen und Apps, denen du vertraust. Darf %4$s einen Fehlerbericht hochladen?" + "Zulassen" + "Ablehnen" diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml index 316adafe5..cb9f34fef 100644 --- a/res/values-el/strings.xml +++ b/res/values-el/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "Κορυφαία χρήση δικαιώματος τα τελευταία 15 λεπτά" "Κορυφαία χρήση αδειών το τελευταίο 1 λεπτό" "Εφαρμογές" - - - - + "Φιλτράρισμα κατά: %1$s" + "Κατάργηση φίλτρου" "Φιλτράρισμα ανά" "Φιλτράρισμα κατά άδεια" "Περισσότερες άδειες" "Περισσότερες προσβάσεις" "Πρόσφατες" - - + "Ανανέωση" "Χρήση αδειών εφαρμογής" "Πρόσβαση: %1$s φορές. Συνολική διάρκεια: %2$s. Τελευταία χρήση πριν από %3$s." "Πρόσβαση: %1$s φορές. Τελευταία χρήση πριν από %2$s." @@ -137,11 +134,9 @@ "Η εφαρμογή %1$s είχε πρόσβαση σε %2$s πριν από %3$s." "Η εφαρμογή %1$s δεν απέκτησε πρόσβαση σε %2$s." "Προβολή λεπτομερούς χρήσης αδειών" - - + "Τελευταία πρόσβαση: %1$s" "Επιτρέπονται" - - + "Επιτρέπεται μόνο κατά τη χρήση" "Απορρίφθηκαν" "Εμφάνιση λεπτομερούς χρήσης" @@ -165,22 +160,6 @@ "Υπενθυμίσεις άδειας" "Η εφαρμογή %s χρησιμοποιεί την τοποθεσία σας" "Αυτή η εφαρμογή μπορεί να έχει πάντα πρόσβαση στην τοποθεσία σας. Πατήστε για να αλλάξετε τη ρύθμιση." - "Ο προγραμματιστής της εφαρμογής λέει ότι τα δεδομένα σας μπορεί να:" - "Αν δεν σας αρέσει ο τρόπος με τον οποίο ο προγραμματιστής της εφαρμογής χρησιμοποιεί τα δεδομένα σας, μπορείτε να απορρίψετε την άδεια." - "Για περισσότερες πληροφορίες, μεταβείτε στην εφαρμογή %s." - "Να μεταφορτωθούν στο cloud" - "Να μεταφορτωθούν στο cloud όταν το επιτρέψετε ρητά" - "Να κοινοποιηθούν σε διαφημιζόμενους ή επιχειρήσεις" - "Να κοινοποιηθούν σε διαφημιζόμενους ή επιχειρήσεις όταν το επιτρέψετε ρητά" - "Χρησιμοποιηθούν για τη δημιουργία εσόδων" - "Χρησιμοποιηθούν για τη δημιουργία εσόδων όταν το επιτρέψετε ρητά" - "Αποθηκευτούν και να αναλύονται για πάντα" - "Αποθηκευτούν και να αναλύονται για την περίοδο που προσδιορίσατε" - - Αποθηκευτούν και να αναλύονται για %s εβδομάδες - Αποθηκευτούν και να αναλύονται για 1 εβδομάδα - - "Ο προγραμματιστής της εφαρμογής δεν προσδιόρισε τον τρόπο με τον οποίο η εφαρμογή χρησιμοποιεί τα δεδομένα σας." "Μόνο κατά τη χρήση της εφαρμογής" "Δεν επιτρέπονται άδειες" "Δεν απαγορεύονται άδειες" @@ -205,10 +184,18 @@ "Εφαρμογή μουσικής" "Εφαρμογή Gallery" "Εφαρ. \"τηλέφωνο\" σε λειτ. αυτ." - "Εφαρμογή κλήσης διακ. μεσολ." + + "Εφαρμογή διαλογής κλήσεων" "Συνοδευτική εφαρμογή κλήσης" - - + "Εφαρμογή υποβοήθειας" + "Εφαρμ. προβολής στο αυτοκίνητο" "Σημείωση: Εάν έχετε ορίσει ένα κλείδωμα οθόνης και επανεκκινήσετε τη συσκευή, η εκκίνηση αυτής της εφαρμογής δεν θα είναι δυνατή έως ότου ξεκλειδώσετε τη συσκευή σας." + "Κοινοποίηση δεδομένων εντοπισμού σφαλμάτων" + "Κοινοποίηση λεπτομερ. δεδομ. εντοπισμού σφαλμάτων;" + "Η εφαρμογή %1$s θέλει να ανεβάσει πληροφορίες εντοπισμού σφαλμάτων." + "Κοινοποίηση δεδομένων εντοπισμού σφαλμάτων" + "Η εφαρμογή %1$s ζητάει να ανεβάσει μια αναφορά σφαλμάτων από αυτήν τη συσκευή η οποία λήφθηκε στις %2$s, %3$s. Οι αναφορές σφαλμάτων περιλαμβάνουν προσωπικά στοιχεία σχετικά με τη συσκευή σας ή στοιχεία που έχουν καταγράψει οι εφαρμογές σας, για παράδειγμα, ονόματα χρηστών, δεδομένα τοποθεσίας, αναγνωριστικά συσκευών και πληροφορίες δικτύου. Να κοινοποιείτε αναφορές σφαλμάτων μόνο σε άτομα και εφαρμογές που θεωρείτε ότι μπορείτε να εμπιστευτείτε αυτές τις πληροφορίες. Επιτρέπετε στην εφαρμογή %4$s να ανεβάσει μια αναφορά σφαλμάτων;" + "Να επιτρέπεται" + "Να μην επιτρέπεται" diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml index 689120dfc..96852c74a 100644 --- a/res/values-en-rAU/strings.xml +++ b/res/values-en-rAU/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "Top permission usage in last 15 minutes" "Top permission usage in last 1 minute" "Apps" - - - - + "Filtered by: %1$s" + "Remove filter" "Filter by" "Filter by permissions" "Most permissions" "Most accesses" "Recent" - - + "Refresh" "App permissions usage" "Access: %1$s times. Total duration: %2$s. Last used %3$s ago." "Access: %1$s times. Last used %2$s ago." @@ -137,11 +134,9 @@ "%1$s accessed your %2$s %3$s ago." "%1$s has not accessed your %2$s." "View detailed permissions usage" - - + "Last access: %1$s" "Allowed" - - + "Allowed only while in use" "Denied" "See detailed usage" @@ -165,22 +160,6 @@ "Permission reminders" "%s has been using your location" "This app can always access your location. Tap to change." - "The app developer says that your data may be:" - "If you don’t like how this app developer is using your data you can deny the permission." - "Go to %s for more information." - "Uploaded to cloud" - "Uploaded to cloud when you explicitly allow it" - "Shared with advertisers or businesses" - "Shared with advertisers or businesses when you explicitly allow it" - "Used for monetisation" - "Used for monetisation when you explicitly allow it" - "Saved and analysed forever" - "Saved and analysed for a duration that you specify" - - Saved and analysed for %s weeks - Saved and analysed for 1 week - - "The app developer did not specify how the app uses your data." "Only while app is in use" "No permissions allowed" "No permissions denied" @@ -205,10 +184,18 @@ "Music app" "Gallery app" "Car mode phone app" - "Proxy calling app" + + "Call screening app" "Call companion app" - - + "Assist app" + "Car Projection app" "Note: If you restart your device and have a screen lock set, this app can’t start until you unlock your device." + "Share Debugging Data" + "Share detailed debugging data?" + "%1$s would like to upload debugging information." + "Share Debugging Data" + "%1$s is requesting to upload a bug report from this device taken on %2$s at %3$s. Bug reports include personal information about your device or logged by apps, for example, user names, location data, device identifiers and network information. Only share bug reports with people and apps that you trust with this information. Allow %4$s to upload a bug report?" + "Allow" + "Deny" diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml index 689120dfc..96852c74a 100644 --- a/res/values-en-rCA/strings.xml +++ b/res/values-en-rCA/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "Top permission usage in last 15 minutes" "Top permission usage in last 1 minute" "Apps" - - - - + "Filtered by: %1$s" + "Remove filter" "Filter by" "Filter by permissions" "Most permissions" "Most accesses" "Recent" - - + "Refresh" "App permissions usage" "Access: %1$s times. Total duration: %2$s. Last used %3$s ago." "Access: %1$s times. Last used %2$s ago." @@ -137,11 +134,9 @@ "%1$s accessed your %2$s %3$s ago." "%1$s has not accessed your %2$s." "View detailed permissions usage" - - + "Last access: %1$s" "Allowed" - - + "Allowed only while in use" "Denied" "See detailed usage" @@ -165,22 +160,6 @@ "Permission reminders" "%s has been using your location" "This app can always access your location. Tap to change." - "The app developer says that your data may be:" - "If you don’t like how this app developer is using your data you can deny the permission." - "Go to %s for more information." - "Uploaded to cloud" - "Uploaded to cloud when you explicitly allow it" - "Shared with advertisers or businesses" - "Shared with advertisers or businesses when you explicitly allow it" - "Used for monetisation" - "Used for monetisation when you explicitly allow it" - "Saved and analysed forever" - "Saved and analysed for a duration that you specify" - - Saved and analysed for %s weeks - Saved and analysed for 1 week - - "The app developer did not specify how the app uses your data." "Only while app is in use" "No permissions allowed" "No permissions denied" @@ -205,10 +184,18 @@ "Music app" "Gallery app" "Car mode phone app" - "Proxy calling app" + + "Call screening app" "Call companion app" - - + "Assist app" + "Car Projection app" "Note: If you restart your device and have a screen lock set, this app can’t start until you unlock your device." + "Share Debugging Data" + "Share detailed debugging data?" + "%1$s would like to upload debugging information." + "Share Debugging Data" + "%1$s is requesting to upload a bug report from this device taken on %2$s at %3$s. Bug reports include personal information about your device or logged by apps, for example, user names, location data, device identifiers and network information. Only share bug reports with people and apps that you trust with this information. Allow %4$s to upload a bug report?" + "Allow" + "Deny" diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml index 689120dfc..96852c74a 100644 --- a/res/values-en-rGB/strings.xml +++ b/res/values-en-rGB/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "Top permission usage in last 15 minutes" "Top permission usage in last 1 minute" "Apps" - - - - + "Filtered by: %1$s" + "Remove filter" "Filter by" "Filter by permissions" "Most permissions" "Most accesses" "Recent" - - + "Refresh" "App permissions usage" "Access: %1$s times. Total duration: %2$s. Last used %3$s ago." "Access: %1$s times. Last used %2$s ago." @@ -137,11 +134,9 @@ "%1$s accessed your %2$s %3$s ago." "%1$s has not accessed your %2$s." "View detailed permissions usage" - - + "Last access: %1$s" "Allowed" - - + "Allowed only while in use" "Denied" "See detailed usage" @@ -165,22 +160,6 @@ "Permission reminders" "%s has been using your location" "This app can always access your location. Tap to change." - "The app developer says that your data may be:" - "If you don’t like how this app developer is using your data you can deny the permission." - "Go to %s for more information." - "Uploaded to cloud" - "Uploaded to cloud when you explicitly allow it" - "Shared with advertisers or businesses" - "Shared with advertisers or businesses when you explicitly allow it" - "Used for monetisation" - "Used for monetisation when you explicitly allow it" - "Saved and analysed forever" - "Saved and analysed for a duration that you specify" - - Saved and analysed for %s weeks - Saved and analysed for 1 week - - "The app developer did not specify how the app uses your data." "Only while app is in use" "No permissions allowed" "No permissions denied" @@ -205,10 +184,18 @@ "Music app" "Gallery app" "Car mode phone app" - "Proxy calling app" + + "Call screening app" "Call companion app" - - + "Assist app" + "Car Projection app" "Note: If you restart your device and have a screen lock set, this app can’t start until you unlock your device." + "Share Debugging Data" + "Share detailed debugging data?" + "%1$s would like to upload debugging information." + "Share Debugging Data" + "%1$s is requesting to upload a bug report from this device taken on %2$s at %3$s. Bug reports include personal information about your device or logged by apps, for example, user names, location data, device identifiers and network information. Only share bug reports with people and apps that you trust with this information. Allow %4$s to upload a bug report?" + "Allow" + "Deny" diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml index 689120dfc..96852c74a 100644 --- a/res/values-en-rIN/strings.xml +++ b/res/values-en-rIN/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "Top permission usage in last 15 minutes" "Top permission usage in last 1 minute" "Apps" - - - - + "Filtered by: %1$s" + "Remove filter" "Filter by" "Filter by permissions" "Most permissions" "Most accesses" "Recent" - - + "Refresh" "App permissions usage" "Access: %1$s times. Total duration: %2$s. Last used %3$s ago." "Access: %1$s times. Last used %2$s ago." @@ -137,11 +134,9 @@ "%1$s accessed your %2$s %3$s ago." "%1$s has not accessed your %2$s." "View detailed permissions usage" - - + "Last access: %1$s" "Allowed" - - + "Allowed only while in use" "Denied" "See detailed usage" @@ -165,22 +160,6 @@ "Permission reminders" "%s has been using your location" "This app can always access your location. Tap to change." - "The app developer says that your data may be:" - "If you don’t like how this app developer is using your data you can deny the permission." - "Go to %s for more information." - "Uploaded to cloud" - "Uploaded to cloud when you explicitly allow it" - "Shared with advertisers or businesses" - "Shared with advertisers or businesses when you explicitly allow it" - "Used for monetisation" - "Used for monetisation when you explicitly allow it" - "Saved and analysed forever" - "Saved and analysed for a duration that you specify" - - Saved and analysed for %s weeks - Saved and analysed for 1 week - - "The app developer did not specify how the app uses your data." "Only while app is in use" "No permissions allowed" "No permissions denied" @@ -205,10 +184,18 @@ "Music app" "Gallery app" "Car mode phone app" - "Proxy calling app" + + "Call screening app" "Call companion app" - - + "Assist app" + "Car Projection app" "Note: If you restart your device and have a screen lock set, this app can’t start until you unlock your device." + "Share Debugging Data" + "Share detailed debugging data?" + "%1$s would like to upload debugging information." + "Share Debugging Data" + "%1$s is requesting to upload a bug report from this device taken on %2$s at %3$s. Bug reports include personal information about your device or logged by apps, for example, user names, location data, device identifiers and network information. Only share bug reports with people and apps that you trust with this information. Allow %4$s to upload a bug report?" + "Allow" + "Deny" diff --git a/res/values-en-rXC-television/strings.xml b/res/values-en-rXC-television/strings.xml index 620b66cab..a2ced46d9 100644 --- a/res/values-en-rXC-television/strings.xml +++ b/res/values-en-rXC-television/strings.xml @@ -16,13 +16,13 @@ - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‎‏‎‎‏‏‏‎‏‏‏‏‏‏‎‎‏‏‎‎‎‎‎‎‏‏‏‏‎‎‏‎‎‏‏‎‏‏‏‏‎‏‏‏‎‎‏‎‎‏‎‏‎‏‏‎Deny and don\'t ask again‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‎‎‏‏‏‎‏‏‎‎‏‏‏‎‏‏‎‎‎‏‏‏‏‏‏‎‎‏‎‎‏‏‎‏‎‎‎‏‏‏‏‎‏‏‎‏‏‎‏‏‎‎‎‏‏‏‎You can change this later in Settings > Apps‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‎‎‏‎‏‎‎‎‎‏‏‏‎‎‎‎‎‎‎‎‏‎‎‎‏‎‏‏‎‎‎‎‎‎‎‏‏‏‏‏‎‏‎‏‏‏‎‎‏‎‏‏‎‏‎‎‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ / ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‏‎‏‏‏‎‎‏‎‏‏‏‏‎‏‏‏‎‎‎‏‎‎‏‏‏‏‏‎‎‏‏‏‎‏‏‎‎‎‏‏‏‏‏‎‏‎‎‎‎‏‎‎‎‎Show system apps‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‏‏‎‎‎‏‏‎‏‎‏‎‎‏‏‏‏‏‎‎‏‏‎‏‎‎‏‏‏‏‎‎‏‎‏‎‏‎‎‏‎‏‏‏‏‎‏‎‏‎‎‏‎‎‏‏‏‎App permissions‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‏‏‎‏‏‏‎‎‏‎‎‎‏‏‎‏‎‎‏‎‏‏‎‏‎‏‏‏‎‎‏‏‎‎‎‎‎‎‎‎‎‎‎‏‎‎‏‏‏‎‎‏‏‏‎‎‏‎App permissions‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‏‏‎‎‎‏‏‎‏‎‏‎‏‏‎‏‎‎‏‎‏‎‏‏‎‎‏‎‏‏‏‏‎‎‏‏‏‎‎‏‏‎‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ permissions‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‏‎‏‎‏‏‎‏‏‎‎‏‎‏‏‏‎‏‏‏‏‏‎‎‎‏‏‎‎‎‏‎‎‏‎‎‏‏‎‏‎‏‎‏‎‎‎‎‎‏‎‎‏‏‏‎‎Additional permissions‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‏‎‏‏‏‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‎‏‏‏‎‏‎‏‎‎‏‏‏‎‏‏‏‎‏‏‎‏‏‏‏‏‏‎‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ permissions‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‎‏‎‎‏‏‏‎‏‏‏‏‏‏‎‎‏‏‎‎‎‎‎‎‏‏‏‏‎‎‏‎‎‏‏‎‏‏‏‏‎‏‏‏‎‎‏‎‎‏‎‏‎‏‏‎Deny and don\'t ask again‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‎‎‏‏‏‎‏‏‎‎‏‏‏‎‏‏‎‎‎‏‏‏‏‏‏‎‎‏‎‎‏‏‎‏‎‎‎‏‏‏‏‎‏‏‎‏‏‎‏‏‎‎‎‏‏‏‎You can change this later in Settings > Apps‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‎‎‏‎‏‎‎‎‎‏‏‏‎‎‎‎‎‎‎‎‏‎‎‎‏‎‏‏‎‎‎‎‎‎‎‏‏‏‏‏‎‏‎‏‏‏‎‎‏‎‏‏‎‏‎‎‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ / ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‏‎‏‏‏‎‎‏‎‏‏‏‏‎‏‏‏‎‎‎‏‎‎‏‏‏‏‏‎‎‏‏‏‎‏‏‎‎‎‏‏‏‏‏‎‏‎‎‎‎‏‎‎‎‎Show system apps‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‏‏‎‎‎‏‏‎‏‎‏‎‎‏‏‏‏‏‎‎‏‏‎‏‎‎‏‏‏‏‎‎‏‎‏‎‏‎‎‏‎‏‏‏‏‎‏‎‏‎‎‏‎‎‏‏‏‎App permissions‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‏‏‎‏‏‏‎‎‏‎‎‎‏‏‎‏‎‎‏‎‏‏‎‏‎‏‏‏‎‎‏‏‎‎‎‎‎‎‎‎‎‎‎‏‎‎‏‏‏‎‎‏‏‏‎‎‏‎App permissions‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‏‏‎‎‎‏‏‎‏‎‏‎‏‏‎‏‎‎‏‎‏‎‏‏‎‎‏‎‏‏‏‏‎‎‏‏‏‎‎‏‏‎‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ permissions‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‏‎‏‎‏‏‎‏‏‎‎‏‎‏‏‏‎‏‏‏‏‏‎‎‎‏‏‎‎‎‏‎‎‏‎‎‏‏‎‏‎‏‎‏‎‎‎‎‎‏‎‎‏‏‏‎‎Additional permissions‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‏‎‏‏‏‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‎‏‏‏‎‏‎‏‎‎‏‏‏‎‏‏‏‎‏‏‎‏‏‏‏‏‏‎‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ permissions‎‏‎‎‏‎" diff --git a/res/values-en-rXC-watch/strings.xml b/res/values-en-rXC-watch/strings.xml index efaf804af..6449362c9 100644 --- a/res/values-en-rXC-watch/strings.xml +++ b/res/values-en-rXC-watch/strings.xml @@ -16,10 +16,10 @@ - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‏‏‎‎‏‎‎‎‎‎‏‎‏‏‏‏‏‎‏‎‏‏‏‏‎‎‎‎‏‎‏‎‏‎‎‎‏‏‎‏‏‏‎‏‎‏‏‎‏‎‏‏‏‏‏‎‎Deny, don\'t ask again‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‎‎‎‎‏‏‎‏‎‏‎‏‏‏‎‎‏‎‎‏‏‏‏‏‎‏‎‏‏‎‎‏‏‏‏‎‏‎‏‎‎‏‎‎‎‎‏‎‏‎‎‏‏‏‏‎‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ / ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‏‎‎‏‏‎‎‎‏‏‏‏‎‏‏‏‎‏‏‎‎‏‏‏‎‏‏‏‏‎‎‎‎‏‏‎‎‎‎‎‎‏‎‏‎‏‎‏‏‎‏‏‎‎‏‏‎Show system apps‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‎‏‎‎‎‏‏‏‏‎‎‏‎‎‏‏‎‏‎‎‎‏‏‏‎‎‎‎‏‏‎‏‎‎‎‏‏‎‎‎‏‏‎‏‏‏‏‎Can\'t be changed‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‎‏‏‎‏‎‎‎‎‎‎‎‎‎‏‎‎‎‏‏‎‎‎‏‎‎‎‎‏‏‏‎‎‎‎‎‏‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎‎‏‏‏‎‎Yes‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‏‎‏‎‏‏‎‎‎‎‏‎‎‏‎‏‎‏‏‎‎‎‎‏‏‏‎‎‏‏‏‎‎‏‎‏‎‎‏‏‏‎‏‎‏‏‎‏‎‏‏‏‏‎‏‏‎Cancel‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‏‏‎‎‏‎‎‎‎‎‏‎‏‏‏‏‏‎‏‎‏‏‏‏‎‎‎‎‏‎‏‎‏‎‎‎‏‏‎‏‏‏‎‏‎‏‏‎‏‎‏‏‏‏‏‎‎Deny, don\'t ask again‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‎‎‎‎‏‏‎‏‎‏‎‏‏‏‎‎‏‎‎‏‏‏‏‏‎‏‎‏‏‎‎‏‏‏‏‎‏‎‏‎‎‏‎‎‎‎‏‎‏‎‎‏‏‏‏‎‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ / ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‏‎‎‏‏‎‎‎‏‏‏‏‎‏‏‏‎‏‏‎‎‏‏‏‎‏‏‏‏‎‎‎‎‏‏‎‎‎‎‎‎‏‎‏‎‏‎‏‏‎‏‏‎‎‏‏‎Show system apps‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‎‏‎‎‎‏‏‏‏‎‎‏‎‎‏‏‎‏‎‎‎‏‏‏‎‎‎‎‏‏‎‏‎‎‎‏‏‎‎‎‏‏‎‏‏‏‏‎Can\'t be changed‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‎‏‏‎‏‎‎‎‎‎‎‎‎‎‏‎‎‎‏‏‎‎‎‏‎‎‎‎‏‏‏‎‎‎‎‎‏‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎‎‏‏‏‎‎Yes‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‏‎‏‎‏‏‎‎‎‎‏‎‎‏‎‏‎‏‏‎‎‎‎‏‏‏‎‎‏‏‏‎‎‏‎‏‎‎‏‏‏‎‏‎‏‏‎‏‎‏‏‏‏‎‏‏‎Cancel‎‏‎‎‏‎" diff --git a/res/values-en-rXC/strings.xml b/res/values-en-rXC/strings.xml index 4de099ef2..52973f857 100644 --- a/res/values-en-rXC/strings.xml +++ b/res/values-en-rXC/strings.xml @@ -4,9 +4,9 @@ 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. @@ -16,193 +16,186 @@ - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‏‏‎‎‎‎‎‏‏‏‎‏‏‏‎‏‏‏‎‎‏‎‏‏‎‎‏‏‏‎‏‎‎‏‎‎‏‎‎‏‏‏‎‎‎‏‎‏‎‏‏‏‏‎‏‏‎Permission controller‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‎‎‏‏‏‏‎‎‏‎‏‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‎‎‏‏‏‎‎‏‎‏‎‏‎‎‎‏‎‏‎‏‎‏‎‎‎‏‎‎OK‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‏‏‏‏‎‎‎‎‏‎‎‎‎‎‏‎‏‎‏‎‏‎‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‎‎permissions‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‎‎‏‏‏‏‎‎‎‏‎‏‎‎‎‏‏‎‎‎‏‏‏‏‏‏‏‎‎‏‎‏‎‏‎‏‏‏‎‏‎‏‎‎‎‏‎‎‏‏‏‏‎‎Cancel‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‎‎‏‏‎‎‎‏‎‏‏‏‎‏‎‎‏‎‎‏‎‏‎‏‏‎‏‎‏‏‏‎‎‏‏‎‎‎‎‏‎‏‏‎‏‏‏‎‎‏‎App not found‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‏‏‏‎‎‏‎‎‏‎‏‏‎‏‏‎‏‎‏‎‏‎‎‏‎‎‎‎‎‏‏‎‎‏‏‎‎‏‏‏‎‎‏‏‏‏‏‎‏‎‏‎‏‏‎‎‎Deny‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‎‏‎‏‎‏‎‏‏‎‎‎‏‎‎‏‏‏‏‎‏‏‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‏‎‏‏‏‏‏‏‎‏‎‎‎‎‎‎Deny & don’t ask again‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‏‏‏‎‏‎‎‏‎‏‏‎‎‏‎‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‎‎‎‏‎‏‏‏‎More info‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‏‎‎‎‏‎‏‎‏‏‏‏‎‎‎‏‏‏‎‎‏‎‏‎‎‏‏‏‎‎‎‎‏‎‎‎‏‎‎‏‎‎‏‏‎‏‎‎‏‎‏‎‏‏‎Deny anyway‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‏‏‏‎‎‏‎‏‎‏‎‎‎‏‏‏‎‏‏‏‎‎‎‏‎‏‎‎‎‏‏‏‎‎‎‎‏‏‏‏‎‏‎‎‎‏‏‏‎‎‏‏‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ of ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‏‏‎‎‎‏‏‏‏‎‏‎‎‎‏‎‏‎‎‏‎‏‏‏‎‏‎‏‏‏‎‎‏‎‎‎‏‎‎‏‏‏‎‏‏‏‎‏‎‏‎‎‎‎‎‏‎Allow <b>‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎</b> to ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎?‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‏‎‎‎‎‏‏‏‎‎‏‏‎‏‏‎‎‎‎‏‏‎‎‎‎‏‏‏‏‎‏‏‎‏‏‎‎‎‏‏‎‏‏‏‎‎‏‏‎‎‎‎‎‏‏‏‎Always allow <b>‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎</b> to ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎?‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‎‏‎‎‎‎‏‏‎‏‏‎‎‏‏‎‎‏‏‎‏‏‏‎‏‏‏‎‎‎‎‎‎‎‎‏‏‏‎‎‎‏‎‏‏‎‏‏‎‏‏‏‏‏‎Only while using app‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎‏‏‎‎‎‎‎‎‏‏‏‏‎‏‎‎‏‏‎‏‏‎‏‏‏‏‎‎‎‎‎‏‏‏‎‎‏‏‏‏‎‏‎‎‏‏‎‏‎‎‏‎‏‎‏‎‎Always‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‏‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‎‎‏‏‎‏‏‎‎‏‎‎‎‏‎‏‏‎‎‏‎‎‏‎‏‎‎‎‎‏‏‏‏‎‏‏‎‎Deny and don’t ask again‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‎‎‏‏‎‏‏‎‏‎‏‎‎‏‎‎‏‏‎‏‎‎‎‏‎‎‎‏‎‎‎‎‎‎‎‎‏‎‎‎‏‎‎‎‏‏‎‎‏‎‎‎‏‎‏‎‎‏‎‎‏‏‎%1$d‎‏‎‎‏‏‏‎ disabled‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‏‎‏‏‏‎‎‎‏‏‎‏‎‎‎‎‎‎‎‏‎‎‏‎‎‏‎‎‎‎‏‏‎‏‏‏‎‏‏‏‏‎‏‏‎‏‏‎‏‎‏‏‎‎all disabled‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‏‎‏‏‎‎‎‏‎‎‎‏‎‎‎‏‏‎‎‎‎‎‏‎‎‎‎‏‏‏‏‎‎‎‏‎‎‏‎‏‏‎‎‏‏‏‎‎‏‎‏‏‎‏‏‏‎none disabled‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‏‏‎‏‎‏‎‏‎‎‎‎‏‎‎‏‏‏‏‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‎‎‏‎‏‏‏‏‏‏‏‎‎‎‏‎‎‏‏‎‎‎Allow‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‎‎‏‏‏‎‏‎‏‎‎‎‏‎‎‎‏‎‏‎‏‏‏‎‏‎‎‎‎‎‏‏‏‏‎‎‎‏‎‏‏‎‏‏‏‏‎‏‏‏‎‎‏‎‎Allow all the time‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‏‎‏‎‎‏‏‏‏‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‏‎‎‎‎‏‏‎‏‏‎‏‏‎‎‏‎‏‏‎‏‎‏‎‎‏‏‎Allow only while the app is in use‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‎‏‏‎‎‎‏‎‎‎‎‎‏‏‎‎‏‎‎‏‎‏‏‏‏‎‎‎‏‏‏‎‏‏‎‏‏‏‎‏‏‏‏‏‎‎‏‎‏‎‏‏‏‏‏‎Apps‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‏‎‎‎‏‏‏‎‏‎‏‏‏‎‎‏‏‏‎‏‎‏‎‏‏‏‎‎‎‎‏‎‏‎‏‎‏‏‎‏‎‎‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎App permissions‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‎‏‏‎‎‏‏‎‎‏‎‎‏‏‏‎‏‎‎‏‎‏‏‎‏‏‏‏‏‏‎‎‎‏‏‎‎‏‏‏‏‎‎‏‎‏‏‏‎‏‏‏‏‎‎Don\'t ask again‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‏‎‎‎‏‏‎‎‎‏‎‏‎‎‎‎‏‎‎‎‏‎‎‎‏‎‎‏‎‎‏‏‎‏‏‏‏‏‏‏‎‎‏‏‎‎‎‎No permissions‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‏‏‏‏‎‎‏‏‎‎‏‏‏‏‎‏‎‎‎‏‏‎‏‎‏‎‏‎‎‏‏‎‎‏‏‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‎‎Additional permissions‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‎‏‏‏‏‏‎‏‎‏‎‎‏‎‎‎‎‏‏‎‎‎‏‏‏‏‎‏‎‎‎‏‏‎‎‏‎‏‏‎‎‏‎‎‎‎‎‏‏‏‎‎‏‎‎Open app info‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‏‏‎‎‎‎‎‏‏‏‎‏‏‏‎‏‏‏‎‎‏‎‏‏‎‎‏‏‏‎‏‎‎‏‎‎‏‎‎‏‏‏‎‎‎‏‎‏‎‏‏‏‏‎‏‏‎Permission controller‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‎‎‏‏‏‏‎‎‏‎‏‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‎‎‏‏‏‎‎‏‎‏‎‏‎‎‎‏‎‏‎‏‎‏‎‎‎‏‎‎OK‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‏‏‏‏‎‎‎‎‏‎‎‎‎‎‏‎‏‎‏‎‏‎‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‏‎‎permissions‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‎‎‏‏‏‏‎‎‎‏‎‏‎‎‎‏‏‎‎‎‏‏‏‏‏‏‏‎‎‏‎‏‎‏‎‏‏‏‎‏‎‏‎‎‎‏‎‎‏‏‏‏‎‎Cancel‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‎‎‏‏‎‎‎‏‎‏‏‏‎‏‎‎‏‎‎‏‎‏‎‏‏‎‏‎‏‏‏‎‎‏‏‎‎‎‎‏‎‏‏‎‏‏‏‎‎‏‎App not found‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‏‏‏‎‎‏‎‎‏‎‏‏‎‏‏‎‏‎‏‎‏‎‎‏‎‎‎‎‎‏‏‎‎‏‏‎‎‏‏‏‎‎‏‏‏‏‏‎‏‎‏‎‏‏‎‎‎Deny‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‎‏‎‏‎‏‎‏‏‎‎‎‏‎‎‏‏‏‏‎‏‏‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‏‎‏‏‏‏‏‏‎‏‎‎‎‎‎‎Deny & don’t ask again‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‏‏‏‎‏‎‎‏‎‏‏‎‎‏‎‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‎‎‎‏‎‏‏‏‎More info‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‏‎‎‎‏‎‏‎‏‏‏‏‎‎‎‏‏‏‎‎‏‎‏‎‎‏‏‏‎‎‎‎‏‎‎‎‏‎‎‏‎‎‏‏‎‏‎‎‏‎‏‎‏‏‎Deny anyway‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‏‏‏‎‎‏‎‏‎‏‎‎‎‏‏‏‎‏‏‏‎‎‎‏‎‏‎‎‎‏‏‏‎‎‎‎‏‏‏‏‎‏‎‎‎‏‏‏‎‎‏‏‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ of ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‏‏‎‎‎‏‏‏‏‎‏‎‎‎‏‎‏‎‎‏‎‏‏‏‎‏‎‏‏‏‎‎‏‎‎‎‏‎‎‏‏‏‎‏‏‏‎‏‎‏‎‎‎‎‎‏‎Allow <b>‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎</b> to ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎?‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‏‎‎‎‎‏‏‏‎‎‏‏‎‏‏‎‎‎‎‏‏‎‎‎‎‏‏‏‏‎‏‏‎‏‏‎‎‎‏‏‎‏‏‏‎‎‏‏‎‎‎‎‎‏‏‏‎Always allow <b>‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎</b> to ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎?‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‎‏‎‎‎‎‏‏‎‏‏‎‎‏‏‎‎‏‏‎‏‏‏‎‏‏‏‎‎‎‎‎‎‎‎‏‏‏‎‎‎‏‎‏‏‎‏‏‎‏‏‏‏‏‎Only while using app‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎‏‏‎‎‎‎‎‎‏‏‏‏‎‏‎‎‏‏‎‏‏‎‏‏‏‏‎‎‎‎‎‏‏‏‎‎‏‏‏‏‎‏‎‎‏‏‎‏‎‎‏‎‏‎‏‎‎Always‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‏‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‎‎‏‏‎‏‏‎‎‏‎‎‎‏‎‏‏‎‎‏‎‎‏‎‏‎‎‎‎‏‏‏‏‎‏‏‎‎Deny and don’t ask again‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‎‎‏‏‎‏‏‎‏‎‏‎‎‏‎‎‏‏‎‏‎‎‎‏‎‎‎‏‎‎‎‎‎‎‎‎‏‎‎‎‏‎‎‎‏‏‎‎‏‎‎‎‏‎‏‎‎‏‎‎‏‏‎%1$d‎‏‎‎‏‏‏‎ disabled‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‏‎‏‏‏‎‎‎‏‏‎‏‎‎‎‎‎‎‎‏‎‎‏‎‎‏‎‎‎‎‏‏‎‏‏‏‎‏‏‏‏‎‏‏‎‏‏‎‏‎‏‏‎‎all disabled‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‏‎‏‏‎‎‎‏‎‎‎‏‎‎‎‏‏‎‎‎‎‎‏‎‎‎‎‏‏‏‏‎‎‎‏‎‎‏‎‏‏‎‎‏‏‏‎‎‏‎‏‏‎‏‏‏‎none disabled‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‏‏‎‏‎‏‎‏‎‎‎‎‏‎‎‏‏‏‏‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‎‎‏‎‏‏‏‏‏‏‏‎‎‎‏‎‎‏‏‎‎‎Allow‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‎‎‏‏‏‎‏‎‏‎‎‎‏‎‎‎‏‎‏‎‏‏‏‎‏‎‎‎‎‎‏‏‏‏‎‎‎‏‎‏‏‎‏‏‏‏‎‏‏‏‎‎‏‎‎Allow all the time‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‏‎‏‎‎‏‏‏‏‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‏‎‎‎‎‏‏‎‏‏‎‏‏‎‎‏‎‏‏‎‏‎‏‎‎‏‏‎Allow only while the app is in use‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‎‏‏‎‎‎‏‎‎‎‎‎‏‏‎‎‏‎‎‏‎‏‏‏‏‎‎‎‏‏‏‎‏‏‎‏‏‏‎‏‏‏‏‏‎‎‏‎‏‎‏‏‏‏‏‎Apps‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‏‎‎‎‏‏‏‎‏‎‏‏‏‎‎‏‏‏‎‏‎‏‎‏‏‏‎‎‎‎‏‎‏‎‏‎‏‏‎‏‎‎‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎App permissions‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‎‏‏‎‎‏‏‎‎‏‎‎‏‏‏‎‏‎‎‏‎‏‏‎‏‏‏‏‏‏‎‎‎‏‏‎‎‏‏‏‏‎‎‏‎‏‏‏‎‏‏‏‏‎‎Don\'t ask again‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‏‎‎‎‏‏‎‎‎‏‎‏‎‎‎‎‏‎‎‎‏‎‎‎‏‎‎‏‎‎‏‏‎‏‏‏‏‏‏‏‎‎‏‏‎‎‎‎No permissions‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‏‏‏‏‎‎‏‏‎‎‏‏‏‏‎‏‎‎‎‏‏‎‏‎‏‎‏‎‎‏‏‎‎‏‏‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‎‎Additional permissions‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‎‏‏‏‏‏‎‏‎‏‎‎‏‎‎‎‎‏‏‎‎‎‏‏‏‏‎‏‎‎‎‏‏‎‎‏‎‏‏‎‎‏‎‎‎‎‎‏‏‏‎‎‏‎‎Open app info‎‏‎‎‏‎" - ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‏‏‏‎‎‏‎‏‏‎‏‏‎‏‏‏‎‎‏‎‏‎‎‏‏‎‎‎‎‏‎‎‎‏‎‎‎‎‎‏‎‏‏‎‏‎‎‎‏‏‏‏‎‎‎‏‎‎‏‏‎%1$d‎‏‎‎‏‏‏‎ more‎‏‎‎‏‎ - ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‏‏‏‎‎‏‎‏‏‎‏‏‎‏‏‏‎‎‏‎‏‎‎‏‏‎‎‎‎‏‎‎‎‏‎‎‎‎‎‏‎‏‏‎‏‎‎‎‏‏‏‏‎‎‎‏‎‎‏‏‎%1$d‎‏‎‎‏‏‏‎ more‎‏‎‎‏‎ + ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‏‏‏‎‎‏‎‏‏‎‏‏‎‏‏‏‎‎‏‎‏‎‎‏‏‎‎‎‎‏‎‎‎‏‎‎‎‎‎‏‎‏‏‎‏‎‎‎‏‏‏‏‎‎‎‏‎‎‏‏‎%1$d‎‏‎‎‏‏‏‎ more‎‏‎‎‏‎ + ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‏‏‏‎‎‏‎‏‏‎‏‏‎‏‏‏‎‎‏‎‏‎‎‏‏‎‎‎‎‏‎‎‎‏‎‎‎‎‎‏‎‏‏‎‏‎‎‎‏‏‏‏‎‎‎‏‎‎‏‏‎%1$d‎‏‎‎‏‏‏‎ more‎‏‎‎‏‎ - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‎‎‎‎‎‏‏‎‎‏‎‏‏‏‏‎‎‏‎‏‎‎‎‎‏‏‎‏‎‎‎‎‎‏‏‏‏‏‎‎‏‎‎This app was designed for an older version of Android. Denying permission may cause it to no longer function as intended.‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‏‎‎‏‏‎‏‏‎‏‏‎‎‎‏‎‎‎‎‏‏‎‎‎‎‎‎‏‏‎‏‏‎‏‏‏‎‏‏‏‎‏‏‎‎‏‎‎‎‏‏‎‎‏‎‏‎perform an unknown action‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‎‏‎‎‏‎‏‎‎‏‎‏‎‏‎‎‎‎‎‎‎‎‏‎‎‎‏‏‎‏‎‎‏‏‎‎‏‏‎‏‎‎‏‎‏‎‏‎‎‏‏‏‏‎‎‏‎‎‏‏‎%1$d‎‏‎‎‏‏‏‎ of ‎‏‎‎‏‏‎%2$d‎‏‎‎‏‏‏‎ apps allowed‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‏‎‏‎‎‏‏‎‏‎‎‎‏‏‎‏‏‏‎‎‏‎‎‏‏‎‏‏‏‏‎‏‎‏‏‏‎‏‎‏‏‏‏‏‏‎‏‏‏‎‎‎‎Recent usage‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‏‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‏‎‎‎‏‎‎‏‎‎‏‎‎‏‏‏‏‎‎‎‏‎‎‏‏‏‎‏‏‏‏‎‏‏‏‏‎View details‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‎‎‏‎‏‎‎‏‎‏‏‎‎‎‎‏‏‏‎‎‏‏‎‎‏‎‎‏‎‎‎‎‏‏‎‏‎‎‎‎‎‎‏‏‏‏‎‏‏‎‎‏‎‏‎Show system‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‏‎‎‎‏‏‏‏‏‎‎‏‏‎‎‎‏‏‎‏‎‎‏‎‎‏‏‎‏‏‏‎‎‎‏‏‎‏‏‎‏‏‎‎‏‏‎‎‏‏‏‎‎‎‏‎‎Hide system‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‎‎‎‏‏‎‎‎‏‎‏‎‎‏‏‎‏‎‎‏‎‏‏‏‏‎‎‎‎‏‎‏‏‏‎‏‎‏‎‎‏‏‏‎No apps‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‏‎‎‏‏‎‎‎‏‎‏‎‏‏‎‏‏‎‏‎‏‏‏‎‏‏‏‏‏‎‏‎‎‏‎‏‎‏‎‏‏‏‏‎‏‎‏‏‏‎‏‎‏‎‏‎‎Location Settings‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‎‎‏‏‎‏‎‎‎‎‎‎‏‎‏‏‏‏‎‏‏‎‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‎‎‏‏‎‎‏‎‎‏‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ is a provider of location services for this device. Location access can be modified from location settings.‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‏‎‏‎‎‎‏‎‎‎‏‎‎‎‏‏‏‎‏‏‎‎‏‏‎‏‏‎‎‎‎‏‏‎‏‎‏‏‏‎‏‎‏‏‎‏‎‎‎‏‏‏‏‎‎‎If you deny this permission, basic features of your device may no longer function as intended.‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‏‏‎‎‏‎‎‎‏‎‏‎‏‏‎‎‎‏‏‎‏‏‎‎‎‏‏‏‎‏‎‎‎‎‏‎‏‎‎‏‎‏‎‏‏‏‎‎‏‏‏‎‏‏‎‎‎Enforced by policy‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‏‏‏‏‏‎‎‏‏‏‎‏‎‏‏‎‏‏‎‏‏‏‎‏‏‎‏‏‎‎‏‎‎‏‎‏‏‏‏‎‎‎‏‎‏‏‏‏‎‎‏‏‏‏‏‏‎‎‎Background access disabled by policy‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‎‏‏‏‎‏‎‏‎‎‏‏‎‎‎‏‏‎‏‏‏‎‏‏‎‏‎‎‏‏‏‏‎‏‏‏‏‎‎‏‏‎‎‏‎‏‏‎‎‏‏‏‏‏‎‎‎Background access enabled by policy‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‎‎‏‏‏‎‎‎‏‏‏‏‏‎‏‏‎‎‏‏‏‎‎‏‎‎‏‎‏‏‎‏‏‏‎‏‏‏‎‎‎‏‏‎‎‎‎‎‎‏‎‎‎Foreground access enabled by policy‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‏‏‎‎‏‎‎‎‏‎‎‏‎‏‏‎‎‏‏‏‏‎‏‏‎‎‎‏‏‎‎‏‎‎‎‎‎‏‏‎‎‎‎‎‎‎‏‏‏‎‎‎‎‎‎‏‏‎Controlled by admin‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‏‏‎‏‏‎‎‎‏‏‎‎‏‎‎‏‏‏‎‏‎‏‎‎‎‏‏‏‏‎‏‎‎‎‎‎‏‎‎‏‏‏‏‎‏‎‏‏‎‎‏‏‎‏‎‏‎‎Background access disabled by admin‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‎‎‏‏‎‏‎‏‎‎‏‎‏‎‏‏‏‎‎‎‎‏‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‏‎‎‎‏‏‎‏‎‏‏‎‏‏‎‏‎‏‎Background access enabled by admin‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‎‎‎‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‏‎‎‎‏‎‏‏‎‏‏‏‏‎‏‎‎‏‏‎‎‎‏‏‏‏‏‎‎Foreground access enabled by admin‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‏‏‎‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‏‎‎‎‎‏‏‎‏‏‎‎‎‏‏‎Permission set by system‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‎‎‎‎‎‏‏‎‎‏‎‏‏‏‏‎‎‏‎‏‎‎‎‎‏‏‎‏‎‎‎‎‎‏‏‏‏‏‎‎‏‎‎This app was designed for an older version of Android. Denying permission may cause it to no longer function as intended.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‏‎‎‏‏‎‏‏‎‏‏‎‎‎‏‎‎‎‎‏‏‎‎‎‎‎‎‏‏‎‏‏‎‏‏‏‎‏‏‏‎‏‏‎‎‏‎‎‎‏‏‎‎‏‎‏‎perform an unknown action‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‎‏‎‎‏‎‏‎‎‏‎‏‎‏‎‎‎‎‎‎‎‎‏‎‎‎‏‏‎‏‎‎‏‏‎‎‏‏‎‏‎‎‏‎‏‎‏‎‎‏‏‏‏‎‎‏‎‎‏‏‎%1$d‎‏‎‎‏‏‏‎ of ‎‏‎‎‏‏‎%2$d‎‏‎‎‏‏‏‎ apps allowed‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‏‎‏‎‎‏‏‎‏‎‎‎‏‏‎‏‏‏‎‎‏‎‎‏‏‎‏‏‏‏‎‏‎‏‏‏‎‏‎‏‏‏‏‏‏‎‏‏‏‎‎‎‎Recent usage‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‏‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‏‎‎‎‏‎‎‏‎‎‏‎‎‏‏‏‏‎‎‎‏‎‎‏‏‏‎‏‏‏‏‎‏‏‏‏‎View details‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‎‎‏‎‏‎‎‏‎‏‏‎‎‎‎‏‏‏‎‎‏‏‎‎‏‎‎‏‎‎‎‎‏‏‎‏‎‎‎‎‎‎‏‏‏‏‎‏‏‎‎‏‎‏‎Show system‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‏‎‎‎‏‏‏‏‏‎‎‏‏‎‎‎‏‏‎‏‎‎‏‎‎‏‏‎‏‏‏‎‎‎‏‏‎‏‏‎‏‏‎‎‏‏‎‎‏‏‏‎‎‎‏‎‎Hide system‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‎‎‎‏‏‎‎‎‏‎‏‎‎‏‏‎‏‎‎‏‎‏‏‏‏‎‎‎‎‏‎‏‏‏‎‏‎‏‎‎‏‏‏‎No apps‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‏‎‎‏‏‎‎‎‏‎‏‎‏‏‎‏‏‎‏‎‏‏‏‎‏‏‏‏‏‎‏‎‎‏‎‏‎‏‎‏‏‏‏‎‏‎‏‏‏‎‏‎‏‎‏‎‎Location Settings‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‎‎‏‏‎‏‎‎‎‎‎‎‏‎‏‏‏‏‎‏‏‎‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‎‎‏‏‎‎‏‎‎‏‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ is a provider of location services for this device. Location access can be modified from location settings.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‏‎‏‎‎‎‏‎‎‎‏‎‎‎‏‏‏‎‏‏‎‎‏‏‎‏‏‎‎‎‎‏‏‎‏‎‏‏‏‎‏‎‏‏‎‏‎‎‎‏‏‏‏‎‎‎If you deny this permission, basic features of your device may no longer function as intended.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‏‏‎‎‏‎‎‎‏‎‏‎‏‏‎‎‎‏‏‎‏‏‎‎‎‏‏‏‎‏‎‎‎‎‏‎‏‎‎‏‎‏‎‏‏‏‎‎‏‏‏‎‏‏‎‎‎Enforced by policy‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‏‏‏‏‏‎‎‏‏‏‎‏‎‏‏‎‏‏‎‏‏‏‎‏‏‎‏‏‎‎‏‎‎‏‎‏‏‏‏‎‎‎‏‎‏‏‏‏‎‎‏‏‏‏‏‏‎‎‎Background access disabled by policy‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‎‏‏‏‎‏‎‏‎‎‏‏‎‎‎‏‏‎‏‏‏‎‏‏‎‏‎‎‏‏‏‏‎‏‏‏‏‎‎‏‏‎‎‏‎‏‏‎‎‏‏‏‏‏‎‎‎Background access enabled by policy‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‎‎‏‏‏‎‎‎‏‏‏‏‏‎‏‏‎‎‏‏‏‎‎‏‎‎‏‎‏‏‎‏‏‏‎‏‏‏‎‎‎‏‏‎‎‎‎‎‎‏‎‎‎Foreground access enabled by policy‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‏‏‎‎‏‎‎‎‏‎‎‏‎‏‏‎‎‏‏‏‏‎‏‏‎‎‎‏‏‎‎‏‎‎‎‎‎‏‏‎‎‎‎‎‎‎‏‏‏‎‎‎‎‎‎‏‏‎Controlled by admin‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‏‏‎‏‏‎‎‎‏‏‎‎‏‎‎‏‏‏‎‏‎‏‎‎‎‏‏‏‏‎‏‎‎‎‎‎‏‎‎‏‏‏‏‎‏‎‏‏‎‎‏‏‎‏‎‏‎‎Background access disabled by admin‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‎‎‏‏‎‏‎‏‎‎‏‎‏‎‏‏‏‎‎‎‎‏‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‏‎‎‎‏‏‎‏‎‏‏‎‏‏‎‏‎‏‎Background access enabled by admin‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‎‎‎‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‏‎‎‎‏‎‏‏‎‏‏‏‏‎‏‎‎‏‏‎‎‎‏‏‏‏‏‎‎Foreground access enabled by admin‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‏‏‎‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‏‎‎‎‎‏‏‎‏‏‎‎‎‏‏‎Permission set by system‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‏‎‎‎‎‏‎‏‏‏‎‎‎‏‎‏‏‎‏‎‎‎‏‏‏‎‏‎‎‏‎‏‎‏‎‏‏‎‏‏‎‎‎‏‎‏‎‎‎‏‏‎‏‏‎Always‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‎‏‏‎‎‎‎‏‎‏‎‏‎‎‏‎‏‎‎‎‎‎‎‎‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‎‏‏‎‎‎‏‎‎‏‎‎‎‏‎Only while using app‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‏‏‏‎‎‎‎‏‏‏‎‏‎‎‎‏‏‏‎‎‏‎‏‏‎‎‎‎‎‎‏‎‎‏‎‎‏‏‎‏‏‏‎‎‎‎‏‏‏‏‏‏‎‎‎Never‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‎‎‏‏‏‏‏‎‏‎‎‏‏‏‏‏‎‎‏‏‎‏‏‏‎‏‎‏‎‎‏‎‎‎‏‏‏‎‏‏‏‎‏‎‎‎‏‎‏‎‏‎‏‏‎‎‏‎Loading…‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‏‎‏‏‏‏‎‏‏‎‏‎‎‏‏‎‏‎‏‎‏‏‎‎‏‎‏‎‏‏‏‎‎‏‏‏‎‎‏‎‏‎‏‏‏‏‏‏‏‏‏‏‎‏‎All permissions‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‎‎‏‎‎‏‏‎‎‎‏‏‏‎‎‎‎‎‎‎‎‏‎‏‏‏‎‏‎‏‎‏‏‏‎‏‏‏‎‎‏‏‎‏‎‏‎‏‎‏‏‏‏‎‏‏‎Other app capabilities‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‎‎‏‎‏‎‏‎‎‎‏‎‏‎‏‏‎‏‎‏‏‏‎‏‎‎‏‏‏‎‏‎‏‎‎‏‏‎‏‏‏‎‎‎‎‏‎‏‎‎‎‏‏‎‎‎Permission request‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‏‎‏‎‏‎‎‎‏‎‏‎‎‎‎‏‎‎‏‏‏‎‎‎‏‏‎‏‎‎‎‎‏‎‏‎‎‏‏‏‏‎‏‏‎‎‎‎‏‏‎‎‏‎‏‎‎Screen overlay detected‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‏‎‏‏‎‏‏‎‏‏‏‏‎‏‏‎‏‎‏‎‏‎‎‎‏‎‎‏‎‏‏‎‎‎‏‏‎‎‎‏‏‏‎‏‎‎‏‏‎‏‏‏‏‏‏‎‎To change this permission setting, you first have to turn off the screen overlay from Settings > Apps‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‏‎‏‎‏‎‏‎‏‎‏‎‏‏‏‎‎‏‎‎‏‏‏‎‎‏‎‎‎‏‏‎‎‏‎‏‎‎‎‎‏‏‏‎‏‎‏‎‏‏‎‎‏‏‎‏‏‎Open settings‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‎‏‎‏‏‎‏‎‎‏‎‎‎‏‎‎‎‎‎‎‎‏‎‏‎‏‏‎‎‎‎‏‎‎‏‎‏‏‎‏‎‎‏‏‏‏‎‏‎‎‏‎‎‏‎Android Wear‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‏‏‎‏‏‎‏‎‎‏‎‏‎‏‏‏‏‎‏‏‏‎‎‎‏‎‎‏‏‎‏‏‏‎‎‏‎‎‎‏‏‏‎‎‏‏‏‏‎‎‏‏‎Install/Uninstall actions not supported on Wear.‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‏‏‎‎‏‏‎‎‏‏‎‎‎‏‎‎‏‎‎‎‏‏‏‏‏‏‏‎‏‏‎‎‎‎‏‏‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‎‎Choose what to allow <b>‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎</b> to access‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‏‏‏‎‏‎‎‎‎‏‎‎‏‏‎‏‎‎‎‎‏‏‎‎‎‎‏‎‎‏‏‏‏‎‎‏‎‎‏‏‏‏‏‏‏‎‎‏‏‏‎‏‎<b>‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎</b> has been updated. Choose what to allow this app to access.‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‎‏‎‎‏‏‎‎‎‎‎‎‏‏‏‏‏‎‎‎‎‏‎‎‏‏‏‎‏‎‏‏‎‎‎‎‏‎‏‏‏‎‏‏‏‏‏‎‏‎‎‎‎‏‎‎Cancel‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‏‏‏‏‏‎‏‏‏‏‎‏‏‎‎‎‏‏‏‎‏‏‎‎‎‎‎‎‏‎‏‎‎‎‏‏‎‏‎‏‎‎‎‏‏‏‏‏‎‏‎‏‏‎‏‏‎Continue‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‎‎‎‏‏‎‏‎‎‏‎‎‏‏‏‎‏‎‏‎‏‏‏‎‏‎‎‎‎‎‏‎‏‎‎‏‏‏‎‎‏‎‎‎‎‏‎‏‎‎‏‏‏‎New permissions‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‏‎‎‏‏‏‎‏‎‎‏‎‎‏‎‏‏‏‎‏‎‏‏‏‎‎‏‏‎‏‎‏‏‎‎‎‎‎‎‎‎‎‏‎‎‏‎‏‎‏‎‏‎‏‏‎‏‎Current permissions‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‏‏‏‎‎‏‏‎‎‏‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‎‏‎‎‎‎‏‎‎‎‏‎‎‏‎‎‎‏‎‏‏‎‏‏‎‎‎‏‎‏‏‎Staging app…‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‎‎‏‏‎‎‎‏‎‏‏‎‎‎‎‎‎‏‎‏‎‎‎‎‎‎‎‏‎‏‎‏‎‏‏‎‎‎‏‎‏‏‏‏‏‎‏‏‎‏‏‏‏‎Unknown‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‏‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‎‏‏‎‎‏‎‏‏‏‏‏‎‏‏‎‏‏‏‏‏‎‏‏‏‏‎‎‏‎‏‏‎‏‎‏‎Permissions usage‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‎‏‏‏‎‎‎‏‏‏‎‏‏‏‎‎‏‏‏‎‏‏‎‎‏‏‏‏‏‎‏‏‎‏‏‎‎‎‎‎‎‏‎‎‏‏‎‎‎‏‏‏‎‏‎‏‎Last access: ‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎ accesses‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‏‎‏‎‏‎‏‎‎‏‎‏‎‎‏‏‎‎‎‎‎‏‏‏‎‏‎‎‎‏‏‏‏‎‎‏‎‏‏‏‎‏‎‎‎‎‎‎‎‏‏‎‎‎‎‏‎Last access: ‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎ accesses (‎‏‎‎‏‏‎%3$s‎‏‎‎‏‏‏‎ in background)‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‎‏‎‎‏‎‏‎‎‏‏‏‎‎‎‎‏‎‏‎‎‎‎‏‎‎‏‏‎‏‎‎‏‏‎‎‏‎‎‎‏‏‎‏‎‏‎‏‎‏‏‏‎Any permission‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‎‎‏‎‏‏‎‏‏‎‎‎‎‏‎‏‏‏‏‏‎‏‎‎‏‏‎‎‏‏‎‏‏‏‏‏‏‎‏‏‏‎‎‎‏‏‎‏‏‏‏‎‏‎‎‏‏‎Any time‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‏‏‎‎‎‎‎‎‏‏‎‏‏‎‏‎‎‎‎‏‎‏‏‏‎‎‏‎‏‏‎‏‏‎‏‏‏‎‎‎‏‎‎‏‏‏‎‎‎‏‎‏‎‎‎Last 7 days‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‎‏‎‏‏‏‎‏‏‏‎‎‏‏‏‎‏‏‎‏‎‏‏‎‏‎‏‏‎‎‎‎‏‎‎‏‏‏‏‏‎‏‎‏‏‎‏‎‏‏‏‎‎‏‎Last 24 hours‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‎‏‎‏‏‎‏‎‎‏‎‎‏‎‎‏‏‎‎‎‎‏‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‎‎‎‎‏‏‏‏‎‏‏‎‎‏‏‎‎‏‏‎Last 1 hour‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‏‎‏‏‏‎‎‎‏‎‏‏‎‏‎‎‎‏‏‎‎‎‎‎‎‎‏‏‎‎‎‎‎‏‎‎‏‏‎‏‎‎‏‎‎‏‎‏‎‎‎‎Last 15 minutes‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‏‎‎‎‏‎‏‏‎‎‎‏‏‏‎‎‎‎‏‎‏‏‎‎‏‎‏‏‏‎‏‏‎‎‏‎‏‎‎‏‎‎‎‎‏‎‏‏‎‎‏‏‏‏‏‎Last 1 minute‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‏‎‏‏‎‎‏‎‏‏‎‏‏‎‎‎‎‎‏‏‏‎‎‎‎‏‎‎‎‎‏‏‎‏‏‏‎‏‎‏‎‎‏‏‎‏‏‎‏‏‎‏‏‎‏‏‎No permission usages‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‎‏‎‎‏‏‏‏‎‎‎‎‏‎‏‏‏‎‎‏‎‏‎‎‎‎‏‏‎‏‏‏‎‎‎‏‎‏‏‎‎‏‎‏‏‏‏‏‏‎‎‏‏‏‎‎‎Access at any time‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‏‎‏‏‏‏‎‎‎‎‎‎‎‏‎‏‏‏‎‏‏‏‏‎‏‏‏‎‎‎‎‏‎‏‏‎‏‏‎‎‎‏‎‎‎‏‎‏‎‎‎‎‏‎‏‎‎Access in last 7 days‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‏‎‎‎‏‏‏‎‏‏‏‏‎‎‏‎‎‏‎‎‏‏‏‎‎‎‎‎‏‎‏‎‏‏‎‎‏‎‏‎‎‎‎‏‏‎‎‎‏‏‎‏‏‏‎Access in last 24 hours‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‎‎‎‏‎‎‏‏‏‎‏‎‏‏‎‎‎‎‏‎‏‏‎‏‎‎‎‏‏‏‎‏‎‎‏‎‏‎‏‏‎‏‎‎‏‎‏‎‏‏‎‎‏‏‎‎‎Access in the last hour‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‏‎‎‏‎‏‎‏‏‎‏‎‎‏‎‏‎‏‎‏‏‏‎‎‏‏‎‎‏‏‎‏‏‏‏‎‏‎‏‏‎‎‎‎‏‏‏‎‎‎‎‎‎‎Access in last 15 minutes‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‎‏‎‎‏‏‏‎‎‏‎‏‎‏‏‎‎‏‎‎‎‎‎‎‏‎‏‏‎‏‎‏‏‏‎‎‎‎‎‎‎‎‎‏‎‏‏‎‏‎‎‏‎Access in last 1 minute‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‎‎‏‎‏‎‏‎‎‎‎‏‎‎‏‏‏‎‏‎‏‎‎‎‎‏‏‎‏‏‏‎‎‎‏‎‏‎‎‎‎‏‏‏‏‎‎‏‏‎‎‏‎‎Top permission usage at any time‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‏‎‎‏‏‎‎‏‎‎‏‎‎‏‏‎‏‏‏‏‎‏‏‏‎‎‏‎‏‎‏‏‏‏‎‏‎‏‏‎‏‎‏‎‏‏‎‏‏‏‎‎‎‏‎‎‏‎Top permission usage in last 7 days‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‏‎‏‏‎‎‏‎‎‏‎‎‎‎‏‎‏‏‎‎‏‎‎‎‎‎‏‎‏‎‏‏‏‏‏‎‏‎‏‏‎‏‎‏‎‎‏‏‏‎‏‏‎‏‏‎Top permission usage in last 24 hours‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‎‎‎‎‏‏‎‎‏‎‎‏‏‏‎‎‎‏‎‏‏‏‎‏‎‏‎‎‎‏‎‎‏‎‎‎‏‎‏‎‎‏‏‏‏‎‏‎‏‎‏‏‎‏‎‎‎Top permission usage in last 1 hour‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‎‏‏‎‎‏‏‏‎‎‎‏‏‎‏‎‏‎‏‎‏‏‎‎‏‏‏‏‎‏‏‎‎‎‎‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‎‏‏‎‏‏‎Top permission usage in last 15 minutes‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‏‎‎‎‎‎‏‏‎‎‏‎‏‏‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‎‎‏‏‏‎‎‏‎Top permission usage in last 1 minute‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‏‏‎‏‏‎‏‏‎‎‎‏‎‎‏‎‏‏‏‏‏‎‎‏‏‎‏‏‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎Apps‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‏‏‎‏‎‎‎‏‏‎‏‎‏‎‎‏‏‎‎‎‎‎‏‏‎‏‏‎‎‏‏‏‎‎‏‎‎‎‏‎‎‏‏‏‏‎‏‎‎‏‎‏‎Filtered by: ‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‎‏‏‎‎‏‎‏‏‎‏‎‏‏‏‏‎‏‏‏‎‏‎‎‎‏‎‎‎‎‏‏‎‏‏‎‏‎‏‎‎‎‏‎‏‏‎‏‏‏‎‏‏‎‏‏‎Remove filter‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‏‏‏‎‎‎‎‎‎‏‏‎‎‎‏‏‎‏‎‏‎‎‏‎‎‏‏‏‎‎‎‎‏‎‎‏‏‏‎‎‎‎‏‏‏‎‏‏‏‏‏‎‏‎‏‎Filter by‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‏‏‎‏‎‏‎‏‎‏‏‎‎‎‏‎‏‏‏‎‏‏‎‎‏‎‎‏‎‎‏‏‎‏‏‏‎‎‏‎‎‎‎‏‎‏‏‎‏‎‎‏‎‎‎Filter by permissions‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎‎‎‏‎‏‎‏‎‏‎‎‎‏‏‏‎‎‎‎‎‎‏‏‎‎‏‎‏‎‏‏‎‏‏‎‏‎‏‏‎‎‎‏‎‎‏‎‏‎‎‎‎‎Most permissions‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‏‏‎‎‏‏‏‏‎‏‎‏‎‏‏‎‏‎‎‎‎‏‎‎‏‏‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎Most accesses‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎‎‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‎‏‎‏‎‏‎‏‎‎‏‏‎‏‏‏‎‏‏‏‏‏‎‎‏‎‏‎‎‎‏‏‏‎‎‎Recent‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‎‏‎‎‏‎‏‎‏‏‎‎‎‏‏‎‏‏‏‎‏‎‏‏‎‎‏‎‏‏‏‎‎‏‎‎‎‎‎‎‎‏‎‎‎‏‏‎‏‎‎‏‏‏‎‎‎Refresh‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‏‎‎‎‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‏‏‎‏‎‏‎‎‏‏‎‎‎‏‏‎‎‏‏‏‎‏‎‏‎‏‎‎‏‏‏‏‎‎App permissions usage‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‏‏‎‎‏‏‎‏‏‏‏‎‎‎‎‎‎‏‎‎‏‏‏‎‏‏‎‎‏‏‎‏‎‎‎‏‏‏‎‏‏‏‎‎‏‎‎‏‎‏‏‎‎Access: ‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ times. Total duration: ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎. Last used ‎‏‎‎‏‏‎%3$s‎‏‎‎‏‏‏‎ ago.‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‏‏‏‏‎‎‎‏‎‎‎‎‏‏‏‎‎‏‏‎‏‏‎‎‏‎‎‎‏‏‏‎‏‏‏‏‎‎‏‏‏‎‏‎‏‎‎‎Access: ‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ times. Last used ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎ ago.‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‏‏‎‏‏‎‏‏‎‏‏‏‏‏‎‏‎‎‏‎‎‎‎‎‏‏‏‎‎‏‏‎‎‎‏‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‎Allow‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‏‏‎‏‏‏‎‎‏‎‏‎‏‏‏‎‎‎‎‏‎‏‎‎‏‎‏‎‏‎‎‎‏‎‎‏‎‏‏‎‎‏‏‏‏‎‏‏‎‏‏‏‏‏‎‎‎Allow all the time‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‏‎‏‏‎‎‏‎‏‎‏‏‏‎‏‎‏‏‎‎‎‎‎‏‎‎‏‎‎‏‎‎‎‏‎‏‎‏‎‎‎‎‎‎‎‎‎‎‎‎‎‏‏‎‏‎Allow only while the app is in use‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‎‏‎‏‎‎‏‎‎‏‏‏‏‎‏‎‏‏‏‏‏‎‏‎‏‎‎‎‏‎‏‎‏‏‎‎‏‏‎‏‎‏‎‏‎‎‎‏‎‎‏‎‎‎‎Deny‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‎‎‎‎‏‎‏‎‏‏‎‎‏‏‏‎‏‎‎‎‏‏‎‎‏‎‏‎‏‏‏‎‎‎‏‎‎‏‎‎‏‏‏‎‎‎‎‏‏‏‏‎‎‎‎‏‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ permission‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‎‏‎‏‎‏‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‎‎‎‎‎‎‎‏‏‎‏‎‎‎‏‎‎‎‏‏‏‎‏‏‎‏‎‏‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ access for ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‎‏‏‏‎‏‏‏‎‏‏‎‎‎‏‎‎‏‎‏‏‏‏‏‏‏‎‏‏‎‎‏‏‏‎‎‎‏‏‎‏‎‏‎‎‏‏‎‎‏‏‏‎‎‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ accessed your ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎ ‎‏‎‎‏‏‎%3$s‎‏‎‎‏‏‏‎ ago.‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‏‎‏‏‏‏‏‏‎‎‏‏‎‎‎‏‏‎‎‎‏‏‏‎‏‏‎‏‏‏‏‎‏‏‎‎‏‏‎‎‏‎‎‎‎‏‎‎‏‏‏‏‎‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ has not accessed your ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎.‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‎‎‏‏‎‎‎‏‏‏‏‎‏‏‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‏‎‏‏‏‏‏‎‎‎‏‏‎‏‎‏‎‏‏‏‏‏‎‎View detailed permissions usage‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‏‏‏‏‎‏‎‎‏‏‎‎‏‎‏‏‎‏‏‎‏‎‏‎‎‎‏‏‏‏‎‏‏‏‎‎‏‏‎‎‎‏‎‏‏‎‏‎‎‎‎‎‎Last access: ‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‎‏‎‎‏‎‎‎‏‎‏‏‎‏‏‏‎‏‏‎‎‎‎‎‎‎‏‎‎‎‏‎‏‏‏‏‏‎‎‏‏‏‏‎‏‏‏‎‎‎‏‏‏‏‎‎Allowed‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‏‎‎‏‏‏‏‎‎‎‎‏‏‎‎‏‎‎‏‎‎‏‏‏‏‎‎‎‏‎‏‎‎‏‎‎‏‏‎‎‎‎‎‎‏‏‏‏‎‎‏‏‏‎Allowed only while in use‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‏‎‎‏‏‏‎‏‎‎‎‏‎‎‏‏‏‎‏‎‎‎‏‎‎‏‎‎‏‎‎‎‎‏‎‏‎‏‏‎‏‏‎‏‎‎‎‎‎‏‏‎‎‎‏‏‎Denied‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‎‏‏‎‎‎‎‎‏‏‏‎‏‏‏‏‎‏‎‎‎‏‎‎‎‏‎‎‎‏‏‎‎‏‏‏‎‏‏‎‏‎‎‎‏‎‏‎‏‏‎‎‏‎‎‎‎See detailed usage‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‏‎‎‎‎‏‎‏‏‏‎‎‎‏‎‏‏‎‏‎‎‎‏‏‏‎‏‎‎‏‎‏‎‏‎‏‏‎‏‏‎‎‎‏‎‏‎‎‎‏‏‎‏‏‎Always‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‎‏‏‎‎‎‎‏‎‏‎‏‎‎‏‎‏‎‎‎‎‎‎‎‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‎‏‏‎‎‎‏‎‎‏‎‎‎‏‎Only while using app‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‏‏‏‎‎‎‎‏‏‏‎‏‎‎‎‏‏‏‎‎‏‎‏‏‎‎‎‎‎‎‏‎‎‏‎‎‏‏‎‏‏‏‎‎‎‎‏‏‏‏‏‏‎‎‎Never‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‎‎‏‏‏‏‏‎‏‎‎‏‏‏‏‏‎‎‏‏‎‏‏‏‎‏‎‏‎‎‏‎‎‎‏‏‏‎‏‏‏‎‏‎‎‎‏‎‏‎‏‎‏‏‎‎‏‎Loading…‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‏‎‏‏‏‏‎‏‏‎‏‎‎‏‏‎‏‎‏‎‏‏‎‎‏‎‏‎‏‏‏‎‎‏‏‏‎‎‏‎‏‎‏‏‏‏‏‏‏‏‏‏‎‏‎All permissions‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‎‎‏‎‎‏‏‎‎‎‏‏‏‎‎‎‎‎‎‎‎‏‎‏‏‏‎‏‎‏‎‏‏‏‎‏‏‏‎‎‏‏‎‏‎‏‎‏‎‏‏‏‏‎‏‏‎Other app capabilities‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‎‎‏‎‏‎‏‎‎‎‏‎‏‎‏‏‎‏‎‏‏‏‎‏‎‎‏‏‏‎‏‎‏‎‎‏‏‎‏‏‏‎‎‎‎‏‎‏‎‎‎‏‏‎‎‎Permission request‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‏‎‏‎‏‎‎‎‏‎‏‎‎‎‎‏‎‎‏‏‏‎‎‎‏‏‎‏‎‎‎‎‏‎‏‎‎‏‏‏‏‎‏‏‎‎‎‎‏‏‎‎‏‎‏‎‎Screen overlay detected‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‏‎‏‏‎‏‏‎‏‏‏‏‎‏‏‎‏‎‏‎‏‎‎‎‏‎‎‏‎‏‏‎‎‎‏‏‎‎‎‏‏‏‎‏‎‎‏‏‎‏‏‏‏‏‏‎‎To change this permission setting, you first have to turn off the screen overlay from Settings > Apps‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‏‎‏‎‏‎‏‎‏‎‏‎‏‏‏‎‎‏‎‎‏‏‏‎‎‏‎‎‎‏‏‎‎‏‎‏‎‎‎‎‏‏‏‎‏‎‏‎‏‏‎‎‏‏‎‏‏‎Open settings‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‎‏‎‏‏‎‏‎‎‏‎‎‎‏‎‎‎‎‎‎‎‏‎‏‎‏‏‎‎‎‎‏‎‎‏‎‏‏‎‏‎‎‏‏‏‏‎‏‎‎‏‎‎‏‎Android Wear‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‏‏‎‏‏‎‏‎‎‏‎‏‎‏‏‏‏‎‏‏‏‎‎‎‏‎‎‏‏‎‏‏‏‎‎‏‎‎‎‏‏‏‎‎‏‏‏‏‎‎‏‏‎Install/Uninstall actions not supported on Wear.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‏‏‎‎‏‏‎‎‏‏‎‎‎‏‎‎‏‎‎‎‏‏‏‏‏‏‏‎‏‏‎‎‎‎‏‏‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‎‎Choose what to allow <b>‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎</b> to access‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‏‏‏‎‏‎‎‎‎‏‎‎‏‏‎‏‎‎‎‎‏‏‎‎‎‎‏‎‎‏‏‏‏‎‎‏‎‎‏‏‏‏‏‏‏‎‎‏‏‏‎‏‎<b>‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎</b> has been updated. Choose what to allow this app to access.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‎‏‎‎‏‏‎‎‎‎‎‎‏‏‏‏‏‎‎‎‎‏‎‎‏‏‏‎‏‎‏‏‎‎‎‎‏‎‏‏‏‎‏‏‏‏‏‎‏‎‎‎‎‏‎‎Cancel‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‏‏‏‏‏‎‏‏‏‏‎‏‏‎‎‎‏‏‏‎‏‏‎‎‎‎‎‎‏‎‏‎‎‎‏‏‎‏‎‏‎‎‎‏‏‏‏‏‎‏‎‏‏‎‏‏‎Continue‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‎‎‎‎‏‏‎‏‎‎‏‎‎‏‏‏‎‏‎‏‎‏‏‏‎‏‎‎‎‎‎‏‎‏‎‎‏‏‏‎‎‏‎‎‎‎‏‎‏‎‎‏‏‏‎New permissions‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‏‎‎‏‏‏‎‏‎‎‏‎‎‏‎‏‏‏‎‏‎‏‏‏‎‎‏‏‎‏‎‏‏‎‎‎‎‎‎‎‎‎‏‎‎‏‎‏‎‏‎‏‎‏‏‎‏‎Current permissions‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‏‏‏‎‎‏‏‎‎‏‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‎‏‎‎‎‎‏‎‎‎‏‎‎‏‎‎‎‏‎‏‏‎‏‏‎‎‎‏‎‏‏‎Staging app…‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‎‎‏‏‎‎‎‏‎‏‏‎‎‎‎‎‎‏‎‏‎‎‎‎‎‎‎‏‎‏‎‏‎‏‏‎‎‎‏‎‏‏‏‏‏‎‏‏‎‏‏‏‏‎Unknown‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‏‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‎‏‏‎‎‏‎‏‏‏‏‏‎‏‏‎‏‏‏‏‏‎‏‏‏‏‎‎‏‎‏‏‎‏‎‏‎Permissions usage‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‎‏‏‏‎‎‎‏‏‏‎‏‏‏‎‎‏‏‏‎‏‏‎‎‏‏‏‏‏‎‏‏‎‏‏‎‎‎‎‎‎‏‎‎‏‏‎‎‎‏‏‏‎‏‎‏‎Last access: ‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎ accesses‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‏‎‏‎‏‎‏‎‎‏‎‏‎‎‏‏‎‎‎‎‎‏‏‏‎‏‎‎‎‏‏‏‏‎‎‏‎‏‏‏‎‏‎‎‎‎‎‎‎‏‏‎‎‎‎‏‎Last access: ‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎ accesses (‎‏‎‎‏‏‎%3$s‎‏‎‎‏‏‏‎ in background)‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‎‏‎‎‏‎‏‎‎‏‏‏‎‎‎‎‏‎‏‎‎‎‎‏‎‎‏‏‎‏‎‎‏‏‎‎‏‎‎‎‏‏‎‏‎‏‎‏‎‏‏‏‎Any permission‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‎‎‏‎‏‏‎‏‏‎‎‎‎‏‎‏‏‏‏‏‎‏‎‎‏‏‎‎‏‏‎‏‏‏‏‏‏‎‏‏‏‎‎‎‏‏‎‏‏‏‏‎‏‎‎‏‏‎Any time‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‏‏‎‎‎‎‎‎‏‏‎‏‏‎‏‎‎‎‎‏‎‏‏‏‎‎‏‎‏‏‎‏‏‎‏‏‏‎‎‎‏‎‎‏‏‏‎‎‎‏‎‏‎‎‎Last 7 days‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‎‏‎‏‏‏‎‏‏‏‎‎‏‏‏‎‏‏‎‏‎‏‏‎‏‎‏‏‎‎‎‎‏‎‎‏‏‏‏‏‎‏‎‏‏‎‏‎‏‏‏‎‎‏‎Last 24 hours‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‎‏‎‏‏‎‏‎‎‏‎‎‏‎‎‏‏‎‎‎‎‏‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‎‎‎‎‏‏‏‏‎‏‏‎‎‏‏‎‎‏‏‎Last 1 hour‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‏‎‏‏‏‎‎‎‏‎‏‏‎‏‎‎‎‏‏‎‎‎‎‎‎‎‏‏‎‎‎‎‎‏‎‎‏‏‎‏‎‎‏‎‎‏‎‏‎‎‎‎Last 15 minutes‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‏‎‎‎‏‎‏‏‎‎‎‏‏‏‎‎‎‎‏‎‏‏‎‎‏‎‏‏‏‎‏‏‎‎‏‎‏‎‎‏‎‎‎‎‏‎‏‏‎‎‏‏‏‏‏‎Last 1 minute‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‏‎‏‏‎‎‏‎‏‏‎‏‏‎‎‎‎‎‏‏‏‎‎‎‎‏‎‎‎‎‏‏‎‏‏‏‎‏‎‏‎‎‏‏‎‏‏‎‏‏‎‏‏‎‏‏‎No permission usages‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‎‏‎‎‏‏‏‏‎‎‎‎‏‎‏‏‏‎‎‏‎‏‎‎‎‎‏‏‎‏‏‏‎‎‎‏‎‏‏‎‎‏‎‏‏‏‏‏‏‎‎‏‏‏‎‎‎Access at any time‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‏‎‏‏‏‏‎‎‎‎‎‎‎‏‎‏‏‏‎‏‏‏‏‎‏‏‏‎‎‎‎‏‎‏‏‎‏‏‎‎‎‏‎‎‎‏‎‏‎‎‎‎‏‎‏‎‎Access in last 7 days‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‏‎‎‎‏‏‏‎‏‏‏‏‎‎‏‎‎‏‎‎‏‏‏‎‎‎‎‎‏‎‏‎‏‏‎‎‏‎‏‎‎‎‎‏‏‎‎‎‏‏‎‏‏‏‎Access in last 24 hours‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‎‎‎‏‎‎‏‏‏‎‏‎‏‏‎‎‎‎‏‎‏‏‎‏‎‎‎‏‏‏‎‏‎‎‏‎‏‎‏‏‎‏‎‎‏‎‏‎‏‏‎‎‏‏‎‎‎Access in the last hour‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‏‎‎‏‎‏‎‏‏‎‏‎‎‏‎‏‎‏‎‏‏‏‎‎‏‏‎‎‏‏‎‏‏‏‏‎‏‎‏‏‎‎‎‎‏‏‏‎‎‎‎‎‎‎Access in last 15 minutes‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‎‏‎‎‏‏‏‎‎‏‎‏‎‏‏‎‎‏‎‎‎‎‎‎‏‎‏‏‎‏‎‏‏‏‎‎‎‎‎‎‎‎‎‏‎‏‏‎‏‎‎‏‎Access in last 1 minute‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‎‎‏‎‏‎‏‎‎‎‎‏‎‎‏‏‏‎‏‎‏‎‎‎‎‏‏‎‏‏‏‎‎‎‏‎‏‎‎‎‎‏‏‏‏‎‎‏‏‎‎‏‎‎Top permission usage at any time‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‏‎‎‏‏‎‎‏‎‎‏‎‎‏‏‎‏‏‏‏‎‏‏‏‎‎‏‎‏‎‏‏‏‏‎‏‎‏‏‎‏‎‏‎‏‏‎‏‏‏‎‎‎‏‎‎‏‎Top permission usage in last 7 days‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‏‎‏‏‎‎‏‎‎‏‎‎‎‎‏‎‏‏‎‎‏‎‎‎‎‎‏‎‏‎‏‏‏‏‏‎‏‎‏‏‎‏‎‏‎‎‏‏‏‎‏‏‎‏‏‎Top permission usage in last 24 hours‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‎‎‎‎‏‏‎‎‏‎‎‏‏‏‎‎‎‏‎‏‏‏‎‏‎‏‎‎‎‏‎‎‏‎‎‎‏‎‏‎‎‏‏‏‏‎‏‎‏‎‏‏‎‏‎‎‎Top permission usage in last 1 hour‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‎‏‏‎‎‏‏‏‎‎‎‏‏‎‏‎‏‎‏‎‏‏‎‎‏‏‏‏‎‏‏‎‎‎‎‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‎‏‏‎‏‏‎Top permission usage in last 15 minutes‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‏‎‎‎‎‎‏‏‎‎‏‎‏‏‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‎‎‏‏‏‎‎‏‎Top permission usage in last 1 minute‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‏‏‎‏‏‎‏‏‎‎‎‏‎‎‏‎‏‏‏‏‏‎‎‏‏‎‏‏‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎Apps‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‏‏‎‏‎‎‎‏‏‎‏‎‏‎‎‏‏‎‎‎‎‎‏‏‎‏‏‎‎‏‏‏‎‎‏‎‎‎‏‎‎‏‏‏‏‎‏‎‎‏‎‏‎Filtered by: ‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‎‏‏‎‎‏‎‏‏‎‏‎‏‏‏‏‎‏‏‏‎‏‎‎‎‏‎‎‎‎‏‏‎‏‏‎‏‎‏‎‎‎‏‎‏‏‎‏‏‏‎‏‏‎‏‏‎Remove filter‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‏‏‏‎‎‎‎‎‎‏‏‎‎‎‏‏‎‏‎‏‎‎‏‎‎‏‏‏‎‎‎‎‏‎‎‏‏‏‎‎‎‎‏‏‏‎‏‏‏‏‏‎‏‎‏‎Filter by‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‏‏‎‏‎‏‎‏‎‏‏‎‎‎‏‎‏‏‏‎‏‏‎‎‏‎‎‏‎‎‏‏‎‏‏‏‎‎‏‎‎‎‎‏‎‏‏‎‏‎‎‏‎‎‎Filter by permissions‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎‎‎‏‎‏‎‏‎‏‎‎‎‏‏‏‎‎‎‎‎‎‏‏‎‎‏‎‏‎‏‏‎‏‏‎‏‎‏‏‎‎‎‏‎‎‏‎‏‎‎‎‎‎Most permissions‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‏‏‎‎‏‏‏‏‎‏‎‏‎‏‏‎‏‎‎‎‎‏‎‎‏‏‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎Most accesses‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎‎‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‎‏‎‏‎‏‎‏‎‎‏‏‎‏‏‏‎‏‏‏‏‏‎‎‏‎‏‎‎‎‏‏‏‎‎‎Recent‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‎‏‎‎‏‎‏‎‏‏‎‎‎‏‏‎‏‏‏‎‏‎‏‏‎‎‏‎‏‏‏‎‎‏‎‎‎‎‎‎‎‏‎‎‎‏‏‎‏‎‎‏‏‏‎‎‎Refresh‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‏‎‎‎‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‏‏‎‏‎‏‎‎‏‏‎‎‎‏‏‎‎‏‏‏‎‏‎‏‎‏‎‎‏‏‏‏‎‎App permissions usage‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‏‏‎‎‏‏‎‏‏‏‏‎‎‎‎‎‎‏‎‎‏‏‏‎‏‏‎‎‏‏‎‏‎‎‎‏‏‏‎‏‏‏‎‎‏‎‎‏‎‏‏‎‎Access: ‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ times. Total duration: ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎. Last used ‎‏‎‎‏‏‎%3$s‎‏‎‎‏‏‏‎ ago.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‏‏‏‏‎‎‎‏‎‎‎‎‏‏‏‎‎‏‏‎‏‏‎‎‏‎‎‎‏‏‏‎‏‏‏‏‎‎‏‏‏‎‏‎‏‎‎‎Access: ‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ times. Last used ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎ ago.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‏‏‎‏‏‎‏‏‎‏‏‏‏‏‎‏‎‎‏‎‎‎‎‎‏‏‏‎‎‏‏‎‎‎‏‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‎Allow‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‏‏‎‏‏‏‎‎‏‎‏‎‏‏‏‎‎‎‎‏‎‏‎‎‏‎‏‎‏‎‎‎‏‎‎‏‎‏‏‎‎‏‏‏‏‎‏‏‎‏‏‏‏‏‎‎‎Allow all the time‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‏‎‏‏‎‎‏‎‏‎‏‏‏‎‏‎‏‏‎‎‎‎‎‏‎‎‏‎‎‏‎‎‎‏‎‏‎‏‎‎‎‎‎‎‎‎‎‎‎‎‎‏‏‎‏‎Allow only while the app is in use‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‎‏‎‏‎‎‏‎‎‏‏‏‏‎‏‎‏‏‏‏‏‎‏‎‏‎‎‎‏‎‏‎‏‏‎‎‏‏‎‏‎‏‎‏‎‎‎‏‎‎‏‎‎‎‎Deny‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‎‎‎‎‏‎‏‎‏‏‎‎‏‏‏‎‏‎‎‎‏‏‎‎‏‎‏‎‏‏‏‎‎‎‏‎‎‏‎‎‏‏‏‎‎‎‎‏‏‏‏‎‎‎‎‏‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ permission‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‎‏‎‏‎‏‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‎‎‎‎‎‎‎‏‏‎‏‎‎‎‏‎‎‎‏‏‏‎‏‏‎‏‎‏‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ access for ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‎‏‏‏‎‏‏‏‎‏‏‎‎‎‏‎‎‏‎‏‏‏‏‏‏‏‎‏‏‎‎‏‏‏‎‎‎‏‏‎‏‎‏‎‎‏‏‎‎‏‏‏‎‎‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ accessed your ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎ ‎‏‎‎‏‏‎%3$s‎‏‎‎‏‏‏‎ ago.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‏‎‏‏‏‏‏‏‎‎‏‏‎‎‎‏‏‎‎‎‏‏‏‎‏‏‎‏‏‏‏‎‏‏‎‎‏‏‎‎‏‎‎‎‎‏‎‎‏‏‏‏‎‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ has not accessed your ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‎‎‏‏‎‎‎‏‏‏‏‎‏‏‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‏‎‏‏‏‏‏‎‎‎‏‏‎‏‎‏‎‏‏‏‏‏‎‎View detailed permissions usage‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‏‏‏‏‎‏‎‎‏‏‎‎‏‎‏‏‎‏‏‎‏‎‏‎‎‎‏‏‏‏‎‏‏‏‎‎‏‏‎‎‎‏‎‏‏‎‏‎‎‎‎‎‎Last access: ‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‎‏‎‎‏‎‎‎‏‎‏‏‎‏‏‏‎‏‏‎‎‎‎‎‎‎‏‎‎‎‏‎‏‏‏‏‏‎‎‏‏‏‏‎‏‏‏‎‎‎‏‏‏‏‎‎Allowed‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‏‎‎‏‏‏‏‎‎‎‎‏‏‎‎‏‎‎‏‎‎‏‏‏‏‎‎‎‏‎‏‎‎‏‎‎‏‏‎‎‎‎‎‎‏‏‏‏‎‎‏‏‏‎Allowed only while in use‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‏‎‎‏‏‏‎‏‎‎‎‏‎‎‏‏‏‎‏‎‎‎‏‎‎‏‎‎‏‎‎‎‎‏‎‏‎‏‏‎‏‏‎‏‎‎‎‎‎‏‏‎‎‎‏‏‎Denied‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‎‏‏‎‎‎‎‎‏‏‏‎‏‏‏‏‎‏‎‎‎‏‎‎‎‏‎‎‎‏‏‎‎‏‏‏‎‏‏‎‏‎‎‎‏‎‏‎‏‏‎‎‏‎‎‎‎See detailed usage‎‏‎‎‏‎" - ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‎‎‏‎‏‎‏‏‏‎‏‏‏‎‏‏‎‎‏‎‏‏‎‎‎‏‎‎‏‏‏‏‎‎‏‏‎‎‏‏‏‏‎‎‎‏‏‎‎‎‎‎‎‎‏‏‎‎‏‎‎‏‏‎%s‎‏‎‎‏‏‏‎ days‎‏‎‎‏‎ - ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‎‎‏‎‏‎‏‏‏‎‏‏‏‎‏‏‎‎‏‎‏‏‎‎‎‏‎‎‏‏‏‏‎‎‏‏‎‎‏‏‏‏‎‎‎‏‏‎‎‎‎‎‎‎‏‏‎1 day‎‏‎‎‏‎ + ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‎‎‏‎‏‎‏‏‏‎‏‏‏‎‏‏‎‎‏‎‏‏‎‎‎‏‎‎‏‏‏‏‎‎‏‏‎‎‏‏‏‏‎‎‎‏‏‎‎‎‎‎‎‎‏‏‎‎‏‎‎‏‏‎%s‎‏‎‎‏‏‏‎ days‎‏‎‎‏‎ + ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‎‎‏‎‏‎‏‏‏‎‏‏‏‎‏‏‎‎‏‎‏‏‎‎‎‏‎‎‏‏‏‏‎‎‏‏‎‎‏‏‏‏‎‎‎‏‏‎‎‎‎‎‎‎‏‏‎1 day‎‏‎‎‏‎ - ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‏‎‏‏‏‏‎‎‏‏‎‏‏‎‏‎‎‎‏‎‏‏‏‎‏‏‏‏‏‏‎‎‎‎‏‏‏‏‏‏‎‎‎‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‎‏‎‎‏‏‎%s‎‏‎‎‏‏‏‎ hours‎‏‎‎‏‎ - ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‏‎‏‏‏‏‎‎‏‏‎‏‏‎‏‎‎‎‏‎‏‏‏‎‏‏‏‏‏‏‎‎‎‎‏‏‏‏‏‏‎‎‎‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎1 hour‎‏‎‎‏‎ + ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‏‎‏‏‏‏‎‎‏‏‎‏‏‎‏‎‎‎‏‎‏‏‏‎‏‏‏‏‏‏‎‎‎‎‏‏‏‏‏‏‎‎‎‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‎‏‎‎‏‏‎%s‎‏‎‎‏‏‏‎ hours‎‏‎‎‏‎ + ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‏‎‏‏‏‏‎‎‏‏‎‏‏‎‏‎‎‎‏‎‏‏‏‎‏‏‏‏‏‏‎‎‎‎‏‏‏‏‏‏‎‎‎‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎1 hour‎‏‎‎‏‎ - ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‎‎‎‎‏‏‎‏‏‎‏‎‏‎‎‏‎‎‎‎‎‎‏‏‎‎‎‎‎‏‏‎‎‎‏‏‎‎‎‏‎‏‏‏‏‎‏‎‎‏‎‏‏‎‏‎‎‎‎‏‎‎‏‏‎%s‎‏‎‎‏‏‏‎ minutes‎‏‎‎‏‎ - ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‎‎‎‎‏‏‎‏‏‎‏‎‏‎‎‏‎‎‎‎‎‎‏‏‎‎‎‎‎‏‏‎‎‎‏‏‎‎‎‏‎‏‏‏‏‎‏‎‎‏‎‏‏‎‏‎‎‎1 minute‎‏‎‎‏‎ + ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‎‎‎‎‏‏‎‏‏‎‏‎‏‎‎‏‎‎‎‎‎‎‏‏‎‎‎‎‎‏‏‎‎‎‏‏‎‎‎‏‎‏‏‏‏‎‏‎‎‏‎‏‏‎‏‎‎‎‎‏‎‎‏‏‎%s‎‏‎‎‏‏‏‎ minutes‎‏‎‎‏‎ + ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‎‎‎‎‏‏‎‏‏‎‏‎‏‎‎‏‎‎‎‎‎‎‏‏‎‎‎‎‎‏‏‎‎‎‏‏‎‎‎‏‎‏‏‏‏‎‏‎‎‏‎‏‏‎‏‎‎‎1 minute‎‏‎‎‏‎ - ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‏‎‏‎‏‎‎‏‎‏‎‎‎‎‏‎‏‎‏‎‎‎‏‎‏‏‎‏‎‎‎‎‏‏‏‏‎‏‎‎‎‏‎‏‏‎‎‎‎‏‎‏‏‏‎‏‎‎‏‎‎‏‏‎%s‎‏‎‎‏‏‏‎ seconds‎‏‎‎‏‎ - ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‏‎‏‎‏‎‎‏‎‏‎‎‎‎‏‎‏‎‏‎‎‎‏‎‏‏‎‏‎‎‎‎‏‏‏‏‎‏‎‎‎‏‎‏‏‎‎‎‎‏‎‏‏‏‎‏‎1 second‎‏‎‎‏‎ - - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‎‏‏‏‎‎‏‎‎‏‏‏‎‏‎‏‎‏‏‏‎‏‎‏‏‏‏‎‏‎‎‎‏‏‏‎‏‏‏‎‏‎‏‏‎‏‎‎‎‎‏‎‎‎‎‎‎Use <b>‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎</b> as your ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎?‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‏‎‏‏‏‏‎‎‎‏‎‏‎‎‎‎‏‎‏‎‎‎‎‎‎‎‏‎‏‎‎‏‎‏‏‎‎‎‏‎‎‏‎‏‏‎‎‎‎‎‎‎‎‏‎‎Use <b>‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎</b> instead of <b>‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎</b> as your ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎?‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‎‏‏‎‎‏‎‏‎‏‏‏‏‏‎‏‎‏‏‏‎‏‎‏‏‎‏‏‎‏‎‏‏‎‏‎‏‎‎‎‎‏‎‎‎‎‎‎‏‏‏‏‎Permission reminders‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‎‏‎‏‎‏‎‎‏‎‎‏‏‏‏‎‏‏‎‏‏‏‎‎‏‎‎‎‎‎‎‎‏‎‎‎‎‏‎‎‏‎‏‏‏‎‏‏‏‎‏‎‏‏‏‎‎‎‏‎‎‏‏‎%s‎‏‎‎‏‏‏‎ has been using your location‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‏‎‏‏‏‎‎‏‎‏‎‏‏‎‎‏‎‏‏‎‏‎‎‎‏‎‏‎‏‎‎‎‎‎‎‎‎‏‎‎‎‏‏‎‎‎‏‎‎‏‏‏‎‎‎This app can always access your location. Tap to change.‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‎‏‎‏‏‎‎‎‏‏‏‏‏‎‏‏‎‎‎‏‏‎‏‏‎‎‎‎‎‏‏‎‏‎‏‏‏‎‏‏‏‏‎‏‏‏‎‏‏‏‏‏‎The app developer says your data may be:‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎‏‏‎‏‏‏‏‏‎‏‎‏‏‏‏‎‎‎‏‏‎‏‎‎‎‎‎‎‎‏‎‏‏‏‏‎‏‎‏‏‏‏‏‏‎‎‏‏‏‎‏‏‎‏‎‎‎If you don’t like how this app developer is using your data you can deny the permission.‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‎‎‏‏‎‎‏‏‏‎‎‎‎‏‎‎‏‎‏‎‏‎‎‎‎‏‏‏‎‎‏‏‏‏‏‎‏‎‎‎‏‏‏‏‎‏‏‎‎‎‎‏‏‏‎‎‎Go to ‎‏‎‎‏‏‎%s‎‏‎‎‏‏‏‎ for more information.‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‏‎‏‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‏‎‏‏‎‎‏‏‎‎‎‏‎‏‎‏‎‎‎‏‏‎‎‎‎‎‏‎‏‎‏‏‏‏‎‏‏‎‎Uploaded to cloud‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‎‎‏‏‎‏‏‏‎‎‎‏‏‎‏‎‏‎‎‎‎‏‏‎‎‎‏‎‎‎‎‎‎‎‎‏‏‏‎‎‏‎‎‏‎‎‎‎‎‎‎‏‏‎‏‏‎Uploaded to cloud when you explicitly allow it‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‎‏‏‎‎‏‏‏‎‎‎‎‏‎‎‏‏‎‎‏‎‏‎‎‏‏‎‏‏‏‎‏‏‎‎‏‏‏‏‎‏‎‏‏‏‎‎‎‎‎‏‏‏‏‎Shared with advertisers or businesses‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‏‎‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‎‎‏‎‏‎‎‏‏‎‎‏‎‏‏‎‏‏‎‎‏‎‎‎‎‎‎‏‎‏‎‏‏‏‏‎‎Shared with advertisers or businesses when you explicitly allow it‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‎‎‎‎‎‎‎‏‏‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎‏‎‏‎‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‎‏‏‏‏‎‎‏‏‏‎Used for monetization‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‏‎‎‎‎‏‏‎‏‎‎‎‏‏‎‎‏‏‎‎‎‏‎‏‎‎‎‏‏‏‎‏‎‏‎‎‏‏‏‏‎‏‏‏‏‎‏‏‎‎‎‎‎‎Used for monetization when you explicitly allow it‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‎‏‏‎‏‎‏‏‏‎‏‎‎‎‏‎‎‏‎‎‎‏‏‎‎‎‏‏‎‏‎‏‏‎‏‎‏‎‏‎‎‏‎‎‏‎‏‎‏‎‏‏‎‏‏‏‎Saved and analyzed forever‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‎‎‎‎‏‏‎‎‎‏‎‏‏‏‎‎‏‎‏‏‏‏‏‎‏‎‏‏‏‏‎‎‏‎‏‏‎‎‎‏‏‎‎‎‎‎‎‎‏‎‏‏‏‏‎Saved and analyzed for a duration you specify‎‏‎‎‏‎" - - ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‎‏‎‏‏‎‏‎‏‏‏‏‏‏‏‎‎‎‏‎‎‎‏‎‏‏‏‎‎‏‏‎‎‏‏‎‏‏‎‏‎‎‏‏‏‏‎‎‏‎‎‏‏‏‏‎‎Saved and analyzed for ‎‏‎‎‏‏‎%s‎‏‎‎‏‏‏‎ weeks‎‏‎‎‏‎ - ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‎‏‎‏‏‎‏‎‏‏‏‏‏‏‏‎‎‎‏‎‎‎‏‎‏‏‏‎‎‏‏‎‎‏‏‎‏‏‎‏‎‎‏‏‏‏‎‎‏‎‎‏‏‏‏‎‎Saved and analyzed for 1 week‎‏‎‎‏‎ + ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‏‎‏‎‏‎‎‏‎‏‎‎‎‎‏‎‏‎‏‎‎‎‏‎‏‏‎‏‎‎‎‎‏‏‏‏‎‏‎‎‎‏‎‏‏‎‎‎‎‏‎‏‏‏‎‏‎‎‏‎‎‏‏‎%s‎‏‎‎‏‏‏‎ seconds‎‏‎‎‏‎ + ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‏‎‏‎‏‎‎‏‎‏‎‎‎‎‏‎‏‎‏‎‎‎‏‎‏‏‎‏‎‎‎‎‏‏‏‏‎‏‎‎‎‏‎‏‏‎‎‎‎‏‎‏‏‏‎‏‎1 second‎‏‎‎‏‎ - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‎‎‎‎‏‎‏‏‎‎‏‎‎‎‎‎‏‏‏‏‎‏‎‎‎‎‏‎‏‏‎‎‏‏‏‎‎‏‏‏‎‏‎‎‏‎‎‏‎‏‎‎‏‏‎The app developer did not specify how the app uses your data.‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‎‎‎‎‏‏‎‎‎‏‎‎‏‎‏‎‏‎‎‏‏‎‎‎‏‎‏‎‏‎‏‎‎‏‎‏‏‏‏‏‎‏‏‏‏‏‏‎‎‎‎‏‏‎‏‏‎Only while app is in use‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‎‏‏‏‎‏‏‎‎‏‏‏‎‏‎‎‎‏‎‎‏‏‎‏‏‎‎‏‏‏‎‎‎‏‎‏‎‎‏‎‏‎‏‎‎‎‎‏‏‎‎‏‎‎‏‎No permissions allowed‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‏‏‎‏‏‎‎‏‏‏‎‏‎‏‎‎‏‏‏‏‎‏‎‎‎‏‏‏‎‎‎‎‏‎‏‎‎‎‎‎‏‎‎No permissions denied‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‎‏‏‎‏‎‏‎‎‏‎‏‎‎‏‏‎‎‎‎‎‎‎‎‏‏‎‏‎‎‎‎‏‎‏‏‏‏‎‏‏‏‎‎‏‏‏‏‏‎‎‎‏‎‎No apps allowed‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‏‏‏‏‏‎‏‎‏‏‏‎‏‎‏‏‎‏‎‎‎‎‎‏‎‎‏‎‎‏‎‏‏‎‏‎‏‏‎‎‏‏‏‎‎‏‏‏‏‏‏‏‎‏‎‎‎No apps denied‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‏‎‏‎‎‏‏‎‏‎‎‏‏‎‎‏‎‎‏‎‏‏‎‏‏‎‎‏‎‎‏‏‎‎‎‏‏‏‏‏‎‏‎‏‏‎‏‏‏‎‏‏‎Open‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‎‏‎‏‎‏‎‏‏‏‎‏‎‏‎‏‎‏‎‎‎‏‎‎‎‏‎‎‎‏‎‎‎‏‎‏‎‎‎‎‏‎‏‏‏‎‏‏‏‏‏‎‎Uninstall‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‎‎‎‎‎‏‏‏‎‎‏‏‎‏‎‎‏‎‏‏‎‏‎‎‏‎‎‎‏‏‎‏‎‏‏‎‎‎‎‏‏‏‎‏‎‏‏‎‏‎‎‏‎‎‏‎‎Force stop‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‏‏‏‏‏‎‎‏‏‎‎‏‎‎‏‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‏‏‏‎‏‏‎‏‏‏‏‏‏‎‏‎‎‎‏‎‎‎Default apps‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‏‏‏‎‏‏‏‏‎‎‏‏‏‎‎‎‏‎‏‎‎‏‏‏‎‎‏‎‎‏‎‏‎‎‏‏‎‎‏‏‎‏‏‏‏‏‏‏‏‎‎‎‎No default apps‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‏‏‎‎‏‏‏‏‎‏‏‎‏‏‎‏‏‏‎‏‏‏‎‏‏‎‏‎‎‎‏‏‎‎‎‎‎‎‎‏‏‎‎‏‎‎‎‎‏‏‎‎‎‎Default for work‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‏‏‎‏‎‏‎‎‏‏‎‏‏‎‏‏‎‎‎‏‏‏‎‎‏‎‏‎‎‎‏‎‎‏‏‎‏‏‎‏‏‎‏‏‏‎‎‎‎‎‏‎‏‎‎None‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‏‎‏‏‎‎‎‎‎‏‎‎‏‏‏‎‏‎‎‏‏‎‏‏‏‏‏‏‏‎‎‏‏‎‏‎‎‎‎‎‏‏‎‏‎‏‎‏‎‏‎‏‏‏‎No apps‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎‎‎‏‏‎‎‏‏‏‎‎‏‎‎‏‏‏‎‎‏‎‎‎‏‎‏‏‎‏‏‎‎‎‏‏‏‏‏‎‎‎‏‎‎‎‏‏‏‏‎‏‏‎‏‎Special app access‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‏‏‎‎‏‏‏‎‏‏‎‏‏‏‏‎‏‏‏‎‏‎‏‎‏‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‎‎‏‎‏‎‎‏‏‏‎‏‎‎‏‏‎No special app access‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‏‎‎‏‏‎‏‏‎‎‎‏‎‏‏‎‏‎‏‏‎‎‎‏‎‏‏‎‎‏‎‎‏‎‏‏‎‎‎‎‎‏‏‎‎‏‏‎‎‏‎‏‎‎‏‎‎No apps‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‏‏‏‎‏‏‏‎‎‎‏‎‏‏‎‏‎‎‏‎‏‎‎‏‎‏‎‏‏‎‎‎‎‏‎‎‏‎‏‎‎‏‎‎‏‏‏‎‏‎‏‎‎‎‏‎Browser app‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‎‏‏‎‏‏‏‏‎‎‎‎‎‎‎‏‏‏‎‏‏‎‏‏‏‎‎‏‎‎‏‎‎‏‏‎‎‏‏‎‏‎‏‏‎‎‏‏‎‎‎‏‏‏‎‏‎Phone app‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‏‏‏‏‎‎‎‎‏‏‏‏‏‎‎‎‏‎‎‏‎‎‏‏‎‏‎‏‏‎‏‏‏‎‏‏‏‏‎‎‏‏‏‎‎‏‎‎SMS app‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‎‎‏‏‎‏‎‏‎‏‎‎‎‎‎‎‏‏‎‎‎‎‏‏‎‏‏‎‎‏‎‏‏‏‎‏‏‏‎‏‏‎‏‏‎‎‎‏‎‎‎‎‎‎Emergency app‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‏‏‏‎‏‏‎‏‏‏‏‏‎‎‏‏‏‏‏‏‎‎‎‎‏‎‏‎‏‎‎‏‎‏‎‎‏‏‎‎‎‎‎‎‎‎‎‏‏‎‎‎‏‎‎Home app‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‏‎‎‎‎‏‏‏‏‎‎‎‎‏‏‏‏‏‎‎‎‏‏‎‏‎‏‎‎‎‏‎‏‏‎‏‏‎‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎Music app‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‎‎‏‏‏‎‎‏‎‎‎‏‎‏‎‏‎‎‎‏‎‏‎‎‎‎‎‎‎‎‏‏‏‎‏‏‎‏‏‏‎‎‎‏‎‎‎‎‎‎‏‎‎‏‎Gallery app‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎‏‎‏‏‏‏‎‏‎‎‏‎‎‏‎‎‏‏‏‏‎‎‎‎‏‎‎‎‏‎‏‎‏‏‎‎‏‎‎‎‏‏‏‎‏‎‎‏‎‎‏‏‏‎Car mode phone app‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‏‏‎‎‎‎‎‎‎‏‏‏‎‏‎‏‏‎‎‎‏‏‏‎‏‎‎‎‏‏‎‎‎‎‏‏‏‎‎‏‏‎‏‏‏‎‎‏‎‎‏‎‏‏‏‏‎Proxy calling app‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‏‏‎‏‏‎‏‎‎‏‏‏‎‏‎‏‏‏‎‏‎‏‎‏‏‏‏‏‏‎‏‎‎‎‎‎‏‏‎‏‏‎‎‏‏‎‏‎‎‏‎‎‏‎‎‏‎‎Call screening app‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‎‎‎‏‏‎‏‎‎‎‎‏‎‎‏‏‎‎‏‏‎‏‏‏‎‎‏‏‎‏‎‎‎‏‎‎‏‎‎‎‏‎‎‏‏‏‎‎‏‏‎‎‏‏‎Call companion app‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‎‏‎‏‎‏‏‎‎‏‏‏‏‎‎‎‏‎‏‏‎‏‏‏‏‎‏‏‎‎‎‎‏‎‎‎‎‏‏‏‏‏‏‎‎‎‎‎‏‎‎‎‎‏‎‎‎Assist app‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‏‏‏‏‎‏‎‏‎‎‏‏‎‏‏‏‎‏‏‎‎‎‎‎‎‏‎‎‏‎‏‏‏‏‏‏‎‏‎‏‏‎‏‏‎‏‎‏‎‏‎‎‏‏‎‎‎Note: If you restart your device and have a screen lock set, this app can’t start until you unlock your device.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‎‏‏‏‎‎‏‎‎‏‏‏‎‏‎‏‎‏‏‏‎‏‎‏‏‏‏‎‏‎‎‎‏‏‏‎‏‏‏‎‏‎‏‏‎‏‎‎‎‎‏‎‎‎‎‎‎Use <b>‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎</b> as your ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎?‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‏‎‏‏‏‏‎‎‎‏‎‏‎‎‎‎‏‎‏‎‎‎‎‎‎‎‏‎‏‎‎‏‎‏‏‎‎‎‏‎‎‏‎‏‏‎‎‎‎‎‎‎‎‏‎‎Use <b>‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎</b> instead of <b>‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎</b> as your ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎?‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‎‏‏‎‎‏‎‏‎‏‏‏‏‏‎‏‎‏‏‏‎‏‎‏‏‎‏‏‎‏‎‏‏‎‏‎‏‎‎‎‎‏‎‎‎‎‎‎‏‏‏‏‎Permission reminders‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‎‏‎‏‎‏‎‎‏‎‎‏‏‏‏‎‏‏‎‏‏‏‎‎‏‎‎‎‎‎‎‎‏‎‎‎‎‏‎‎‏‎‏‏‏‎‏‏‏‎‏‎‏‏‏‎‎‎‏‎‎‏‏‎%s‎‏‎‎‏‏‏‎ has been using your location‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‏‎‏‏‏‎‎‏‎‏‎‏‏‎‎‏‎‏‏‎‏‎‎‎‏‎‏‎‏‎‎‎‎‎‎‎‎‏‎‎‎‏‏‎‎‎‏‎‎‏‏‏‎‎‎This app can always access your location. Tap to change.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‎‎‎‎‏‏‎‎‎‏‎‎‏‎‏‎‏‎‎‏‏‎‎‎‏‎‏‎‏‎‏‎‎‏‎‏‏‏‏‏‎‏‏‏‏‏‏‎‎‎‎‏‏‎‏‏‎Only while app is in use‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‎‏‏‏‎‏‏‎‎‏‏‏‎‏‎‎‎‏‎‎‏‏‎‏‏‎‎‏‏‏‎‎‎‏‎‏‎‎‏‎‏‎‏‎‎‎‎‏‏‎‎‏‎‎‏‎No permissions allowed‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‏‏‎‏‏‎‎‏‏‏‎‏‎‏‎‎‏‏‏‏‎‏‎‎‎‏‏‏‎‎‎‎‏‎‏‎‎‎‎‎‏‎‎No permissions denied‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‎‏‏‎‏‎‏‎‎‏‎‏‎‎‏‏‎‎‎‎‎‎‎‎‏‏‎‏‎‎‎‎‏‎‏‏‏‏‎‏‏‏‎‎‏‏‏‏‏‎‎‎‏‎‎No apps allowed‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‏‏‏‏‏‎‏‎‏‏‏‎‏‎‏‏‎‏‎‎‎‎‎‏‎‎‏‎‎‏‎‏‏‎‏‎‏‏‎‎‏‏‏‎‎‏‏‏‏‏‏‏‎‏‎‎‎No apps denied‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‏‎‏‎‎‏‏‎‏‎‎‏‏‎‎‏‎‎‏‎‏‏‎‏‏‎‎‏‎‎‏‏‎‎‎‏‏‏‏‏‎‏‎‏‏‎‏‏‏‎‏‏‎Open‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‎‏‎‏‎‏‎‏‏‏‎‏‎‏‎‏‎‏‎‎‎‏‎‎‎‏‎‎‎‏‎‎‎‏‎‏‎‎‎‎‏‎‏‏‏‎‏‏‏‏‏‎‎Uninstall‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‎‎‎‎‎‏‏‏‎‎‏‏‎‏‎‎‏‎‏‏‎‏‎‎‏‎‎‎‏‏‎‏‎‏‏‎‎‎‎‏‏‏‎‏‎‏‏‎‏‎‎‏‎‎‏‎‎Force stop‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‏‏‏‏‏‎‎‏‏‎‎‏‎‎‏‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‏‏‏‎‏‏‎‏‏‏‏‏‏‎‏‎‎‎‏‎‎‎Default apps‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‏‏‏‎‏‏‏‏‎‎‏‏‏‎‎‎‏‎‏‎‎‏‏‏‎‎‏‎‎‏‎‏‎‎‏‏‎‎‏‏‎‏‏‏‏‏‏‏‏‎‎‎‎No default apps‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‏‏‎‎‏‏‏‏‎‏‏‎‏‏‎‏‏‏‎‏‏‏‎‏‏‎‏‎‎‎‏‏‎‎‎‎‎‎‎‏‏‎‎‏‎‎‎‎‏‏‎‎‎‎Default for work‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‏‏‎‏‎‏‎‎‏‏‎‏‏‎‏‏‎‎‎‏‏‏‎‎‏‎‏‎‎‎‏‎‎‏‏‎‏‏‎‏‏‎‏‏‏‎‎‎‎‎‏‎‏‎‎None‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‏‎‏‏‎‎‎‎‎‏‎‎‏‏‏‎‏‎‎‏‏‎‏‏‏‏‏‏‏‎‎‏‏‎‏‎‎‎‎‎‏‏‎‏‎‏‎‏‎‏‎‏‏‏‎No apps‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎‎‎‏‏‎‎‏‏‏‎‎‏‎‎‏‏‏‎‎‏‎‎‎‏‎‏‏‎‏‏‎‎‎‏‏‏‏‏‎‎‎‏‎‎‎‏‏‏‏‎‏‏‎‏‎Special app access‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‏‏‎‎‏‏‏‎‏‏‎‏‏‏‏‎‏‏‏‎‏‎‏‎‏‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‎‎‏‎‏‎‎‏‏‏‎‏‎‎‏‏‎No special app access‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‏‎‎‏‏‎‏‏‎‎‎‏‎‏‏‎‏‎‏‏‎‎‎‏‎‏‏‎‎‏‎‎‏‎‏‏‎‎‎‎‎‏‏‎‎‏‏‎‎‏‎‏‎‎‏‎‎No apps‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‏‏‏‎‏‏‏‎‎‎‏‎‏‏‎‏‎‎‏‎‏‎‎‏‎‏‎‏‏‎‎‎‎‏‎‎‏‎‏‎‎‏‎‎‏‏‏‎‏‎‏‎‎‎‏‎Browser app‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‎‏‏‎‏‏‏‏‎‎‎‎‎‎‎‏‏‏‎‏‏‎‏‏‏‎‎‏‎‎‏‎‎‏‏‎‎‏‏‎‏‎‏‏‎‎‏‏‎‎‎‏‏‏‎‏‎Phone app‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‏‏‏‏‎‎‎‎‏‏‏‏‏‎‎‎‏‎‎‏‎‎‏‏‎‏‎‏‏‎‏‏‏‎‏‏‏‏‎‎‏‏‏‎‎‏‎‎SMS app‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‎‎‏‏‎‏‎‏‎‏‎‎‎‎‎‎‏‏‎‎‎‎‏‏‎‏‏‎‎‏‎‏‏‏‎‏‏‏‎‏‏‎‏‏‎‎‎‏‎‎‎‎‎‎Emergency app‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‏‏‏‎‏‏‎‏‏‏‏‏‎‎‏‏‏‏‏‏‎‎‎‎‏‎‏‎‏‎‎‏‎‏‎‎‏‏‎‎‎‎‎‎‎‎‎‏‏‎‎‎‏‎‎Home app‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‏‎‎‎‎‏‏‏‏‎‎‎‎‏‏‏‏‏‎‎‎‏‏‎‏‎‏‎‎‎‏‎‏‏‎‏‏‎‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎Music app‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‎‎‏‏‏‎‎‏‎‎‎‏‎‏‎‏‎‎‎‏‎‏‎‎‎‎‎‎‎‎‏‏‏‎‏‏‎‏‏‏‎‎‎‏‎‎‎‎‎‎‏‎‎‏‎Gallery app‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎‏‎‏‏‏‏‎‏‎‎‏‎‎‏‎‎‏‏‏‏‎‎‎‎‏‎‎‎‏‎‏‎‏‏‎‎‏‎‎‎‏‏‏‎‏‎‎‏‎‎‏‏‏‎Car mode phone app‎‏‎‎‏‎" + + + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‏‏‎‏‏‎‏‎‎‏‏‏‎‏‎‏‏‏‎‏‎‏‎‏‏‏‏‏‏‎‏‎‎‎‎‎‏‏‎‏‏‎‎‏‏‎‏‎‎‏‎‎‏‎‎‏‎‎Call screening app‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‎‎‎‏‏‎‏‎‎‎‎‏‎‎‏‏‎‎‏‏‎‏‏‏‎‎‏‏‎‏‎‎‎‏‎‎‏‎‎‎‏‎‎‏‏‏‎‎‏‏‎‎‏‏‎Call companion app‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‎‏‎‏‎‏‏‎‎‏‏‏‏‎‎‎‏‎‏‏‎‏‏‏‏‎‏‏‎‎‎‎‏‎‎‎‎‏‏‏‏‏‏‎‎‎‎‎‏‎‎‎‎‏‎‎‎Assist app‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‏‎‏‎‎‎‏‏‎‎‏‏‎‎‎‎‏‏‏‎‏‎‏‎‎‏‎‏‏‏‎‏‏‎‎‎‎‎‏‎‎‏‎‎‏‏‏‏‎‏‏‎‏‏‎‏‎Car Projection app‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‏‏‏‏‎‏‎‏‎‎‏‏‎‏‏‏‎‏‏‎‎‎‎‎‎‏‎‎‏‎‏‏‏‏‏‏‎‏‎‏‏‎‏‏‎‏‎‏‎‏‎‎‏‏‎‎‎Note: If you restart your device and have a screen lock set, this app can’t start until you unlock your device.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‎‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‎‎‎‎‎‏‏‎‎‏‎‎‎‏‏‏‎‎‏‎‏‎‏‏‎‏‎‏‏‎‎Share Debugging Data‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‏‎‎‏‏‎‎‎‎‎‎‏‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‎‎‎‎‏‎‏‏‏‎‏‎‏‏‎‎Share detailed debugging data?‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‎‏‎‏‎‏‎‏‏‎‏‎‎‎‏‎‎‏‏‏‎‏‏‎‎‎‏‎‎‎‏‏‏‏‏‎‏‎‏‏‏‏‏‏‎‎‎‏‎‏‎‎‎‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ would like to upload debugging information.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‏‎‎‏‏‏‎‏‏‎‎‏‏‎‎‎‏‎‎‏‏‎‎‏‏‎‎‎‎‏‏‎‎‏‏‎‎‎‎‏‎‏‏‎‎‎‎‏‏‎‎‎‏‎‏‎Share Debugging Data‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‏‎‎‏‎‏‏‏‎‏‎‏‎‎‏‎‎‎‏‏‏‏‎‎‎‏‎‏‎‎‏‎‎‏‏‎‏‏‎‏‎‏‎‎‎‎‏‏‎‎‏‎‏‏‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ is requesting to upload a bug report from this device taken on ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎ at ‎‏‎‎‏‏‎%3$s‎‏‎‎‏‏‏‎. Bug reports include personal information about your device or logged by apps, for example, user names, location data, device identifiers, and network information. Only share bug reports with people and apps you trust with this information. Allow ‎‏‎‎‏‏‎%4$s‎‏‎‎‏‏‏‎ to upload a bug report?‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‏‏‏‎‏‎‏‏‏‏‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‏‎‏‎‏‏‎‏‏‎‎‎‏‏‏‏‎‏‎‏‎‏‎‏‎Allow‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‎‎‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‎‎‏‏‎‎‎‏‏‎‎‎‎‏‏‎‎‏‎‎‎‎‎‏‎‏‎‎‏‎‎‏‎‏‎‎‏‎‎‎Deny‎‏‎‎‏‎" diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml index c7e29d4b1..5cd059ded 100644 --- a/res/values-es-rUS/strings.xml +++ b/res/values-es-rUS/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "Permisos más usados en los últimos 15 minutos" "Permisos más usados en el último minuto" "Apps" - - - - + "Filtrado por: %1$s" + "Quitar filtro" "Filtrar por" "Filtrar por permisos" "Mayor cantidad de permisos" "Mayor cantidad de accesos" "Recientes" - - + "Actualizar" "Uso de permisos de la app" "Acceso: %1$s veces Duración total: %2$s. Último uso: hace %3$s" "Acceso: %1$s veces Último uso: hace %2$s" @@ -137,11 +134,9 @@ "%1$s accedió a tu %2$s hace %3$s." "%1$s no accedió a %2$s." "Ver uso de permisos detallado" - - + "Último acceso: %1$s" "Permitidos" - - + "Permitidos solo durante el uso" "Rechazados" "Ver uso detallado" @@ -165,22 +160,6 @@ "Recordatorios de permisos" "%s ha estado usando tu ubicación" "Esta app puede acceder a tu ubicación en todo momento. Presiona para cambiar el permiso." - "El desarrollador de la app menciona las siguientes posibilidades para tus datos:" - "Si no te gusta la manera en que el desarrollador de esta app usa tus datos, puedes denegar el permiso." - "Para obtener más información, accede a %s." - "Se suben a la nube" - "Se suben a la nube cuando lo permites explícitamente" - "Se comparten con anunciantes o empresas" - "Se comparten con anunciantes o empresas cuando lo permites explícitamente" - "Se usan para monetización" - "Se usan para monetización cuando lo permites explícitamente" - "Se guardan y se analizan por siempre" - "Se guardan y se analizan durante el tiempo que especifiques" - - Se guardan y se analizan durante %s semanas - Se guardan y se analizan durante 1 semana - - "El desarrollador de la app no especificó la manera en que la app usa tus datos." "Solo cuando la app está en uso" "No se otorgó ningún permiso" "No se rechazó ningún permiso" @@ -205,10 +184,18 @@ "App de Música" "App de Galería" "App de teléfono en modo auto" - "App de llamadas a proxy" + + "App de filtro de llamadas" "App de llamadas complementaria" - - + "Aplicación de asistencia" + "App de proyección del auto" "Nota: Si reinicias el dispositivo y tienes configurado un bloqueo de pantalla, no podrá iniciarse la app hasta que lo desbloquees." + "Compartir datos de depuración" + "¿Compartir datos detallados de depuración?" + "%1$s quiere subir información de depuración." + "Compartir datos de depuración" + "%1$s solicita subir un informe de errores de este dispositivo generado el %2$s %3$s. Los informes de errores pueden incluir información personal sobre tu dispositivo o registrada por apps, como nombres de usuario, datos de ubicación, identificadores del dispositivo y datos de red. Solo debes compartir los informes de errores con personas y apps de confianza. ¿Permitir que %4$s suba un informe de errores?" + "Permitir" + "Denegar" diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index 05f7ac4af..7fffac15b 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "Permisos más usados en los últimos 15 minutos" "Permisos más usados en el último minuto" "Apps" - - - - + "Filtrados por: %1$s" + "Quitar filtro" "Filtrar por" "Filtrar por permisos" "Mayor número de permisos" "Mayor número de accesos" "Recientes" - - + "Actualizar" "Uso permisos de la aplicación" "Acceso: %1$s veces. Duración total: %2$s. Último uso: hace %3$s." "Acceso: %1$s veces. Último uso: hace %2$s." @@ -137,11 +134,9 @@ "%1$s ha accedido a tu %2$s hace %3$s." "%1$s no ha accedido a tu %2$s." "Ver el uso de permisos detallado" - - + "Último acceso: %1$s" "Permitidos" - - + "Solo se permite mientras se usa" "Denegados" "Ver uso detallado" @@ -165,22 +160,6 @@ "Recordatorios de permisos" "%s ha estado usando tu ubicación" "Esta aplicación puede acceder siempre a tu ubicación. Toca para cambiarlo." - "El desarrollador de la aplicación dice que tus datos se podrán:" - "Si no estás de acuerdo con el uso que hace de tus datos el desarrollador de esta aplicación, puedes denegarle el permiso." - "Accede a %s para obtener más información." - "Subir a la nube" - "Subir a la nube si das tu consentimiento explícito" - "Compartir con anunciantes o empresas" - "Compartir con anunciantes o empresas si das tu consentimiento explícito" - "Usar para obtener ingresos" - "Usar para obtener ingresos si das tu consentimiento explícito" - "Guardar y analizar durante un tiempo ilimitado" - "Guardar y analizar durante el tiempo que especifiques" - - Guardar y analizar durante %s semanas - Guardar y analizar durante 1 semana - - "El desarrollador no ha especificado cómo utilizará tus datos la aplicación." "Solo mientras la aplicación está en uso" "No se ha concedido ningún permiso" "No se ha denegado ningún permiso" @@ -205,10 +184,18 @@ "Aplicación de música" "Aplicación de galería" "App de llamadas en modo coche" - "Aplicación de llamadas proxy" + + "App de filtro de llamadas" "App complementaria de llamadas" - - + "Aplicación de asistencia" + "App de proyección del coche" "Nota: Si reinicias el dispositivo y y has definido un bloqueo de pantalla, esta aplicación no se podrá iniciar hasta que desbloquees el dispositivo." + "Compartir datos de depuración" + "¿Quieres compartir datos de depuración detallados?" + "%1$s quiere subir información de depuración." + "Compartir datos de depuración" + "%1$s quiere subir el informe de errores de este dispositivo, generado el %2$s a las %3$s. Los informes de errores incluyen información personal sobre el dispositivo o datos registrados por las aplicaciones, como nombres de usuario, datos de ubicación, identificadores del dispositivo e información de red. Comparte estos informes únicamente con personas y aplicaciones de confianza. ¿Quieres permitir que %4$s suba un informe de errores?" + "Permitir" + "Denegar" diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml index e3b73f066..d43ac509b 100644 --- a/res/values-et/strings.xml +++ b/res/values-et/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "Populaarseima loa kasutus viimase 15 min jooksul" "Populaarseima loa kasutus viimase 1 minuti jooksul" "Rakendused" - - - - + "Filtreerimisalus: %1$s" + "Eemalda filter" "Filter:" "Filtreeri lubade järgi" "Enim lube" "Kõige rohkem juurdepääsemisi" "Hiljutised" - - + "Värskenda" "Rakenduse lubade kasutus" "Juurdepääs: %1$s korda. Kogukestus: %2$s. Viimati kasutati %3$s tagasi." "Juurdepääs: %1$s korda. Viimati kasutati %2$s tagasi." @@ -137,11 +134,9 @@ "Rakendus %1$s pääses loale %2$s juurde %3$s tagasi." "%1$s pole teie loale %2$s juurde pääsenud." "Kuva lubade kasutamise üksikasjad" - - + "Viimane juurdepääs: %1$s" "Lubatud" - - + "Lubatud ainult kasutuses olles" "Keeldutud" "Kuva üksikasjalik kasutus" @@ -165,22 +160,6 @@ "Loa meeldetuletused" "%s on kasutanud teie asukohta" "See rakendus pääseb teie asukohale alati juurde. Puudutage muutmiseks." - "Rakenduse arendaja ütleb, et teie andmetega võidakse teha järgmist." - "Kui teile ei meeldi, kuidas rakenduse arendaja teie andmeid kasutab, ei pea te luba andma." - "Lisateabe saamiseks avage rakendus %s." - "Laaditakse pilve üles" - "Laaditakse pilve üles, kui seda sõnaselgelt lubate" - "Jagatakse reklaamijate või ettevõtetega" - "Jagatakse reklaamijate või ettevõtetega, kui seda sõnaselgelt lubate" - "Kasutatakse monetiseerimiseks" - "Kasutatakse monetiseerimiseks, kui seda sõnaselgelt lubate" - "Analüüsitakse ja salvestatakse igaveseks" - "Analüüsitakse ja salvestatakse teie määratud ajaks" - - Analüüsitakse ja salvestatakse %s nädalaks - Analüüsitakse ja salvestatakse 1 nädalaks - - "Rakenduse arendaja ei täpsustanud, kuidas rakendus teie andmeid kasutab." "Ainult rakenduse kasutamise ajal" "Ühtegi luba pole antud" "Ükski luba pole keelatud" @@ -205,10 +184,18 @@ "Muusikarakendus" "Galeriirakendus" "Autorežiimi telefonirakendus" - "Puhverserv. kaudu helist. rak." + + "Kõnede filtreerimise rakendus" "Helistamise kaasrakendus" - - + "Abirakendus" + "Auto projektsiooni rakendus" "Märkus Kui taaskäivitate seadme ja olete määranud ekraaniluku, ei saa see rakendus käivituda enne, kui oma seadme avate." + "Silumisandmete jagamine" + "Kas jagada üksikasjalikke silumisandmeid?" + "%1$s soovib üles laadida silumisteavet." + "Silumisandmete jagamine" + "%1$s palub luba sellest seadmest veaaruande üleslaadimiseks (jäädvustati %2$s kell %3$s). Veaaruanded hõlmavad teie seadmega seotud isiklikke andmeid või rakenduste logitud isiklikke andmeid (nt kasutajanimesid, asukohaandmeid, seadme ID-sid ja võrguteavet). Jagage veaaruandeid ainult inimeste ja rakendustega, keda/mida usaldate. Kas lubada rakendusel %4$s veaaruanne üles laadida?" + "Luba" + "Keela" diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml index 0e3d5135b..81c174454 100644 --- a/res/values-eu/strings.xml +++ b/res/values-eu/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "Baimenik erabilienak azken 15 minutuetan" "Baimenik erabilienak azken minutuan" "Aplikazioak" - - - - + "Iragazteko irizpidea: %1$s" + "Kendu iragazkia" "Iragazi honen arabera" "Iragazi baimenen arabera" "Baimen gehien erabili dituztenak" "Erabilienak" "Azkenak" - - + "Freskatu" "Aplikazio-baimenen erabilera" "Sarbidea: %1$s aldiz. Iraupena, guztira: %2$s. Duela %3$s erabili zen azken aldiz." "Sarbidea: %1$s aldiz. Duela %2$s erabili zen azken aldiz." @@ -137,11 +134,9 @@ "%1$s aplikazioak %2$s atzitu du duela %3$s." "%1$s aplikazioak ez du atzitu %2$s." "Ikusi baimenen erabilera xehatua" - - + "Azken sarbidea: %1$s" "Baimenduta" - - + "Erabili bitartean soilik baimenduta" "Ukatuta" "Ikusi erabilera xehea" @@ -165,22 +160,6 @@ "Baimenen abisuak" "%s zure kokapena erabiltzen aritu da" "Aplikazio honek beti atzi dezake kokapena. Sakatu aldatzeko." - "Aplikazioaren garatzaileak datuekin hau gertatuko dela dio:" - "Ez bazaizu gustatzen aplikazioaren garatzaileak zure datuak nola erabiltzen dituen, baimena ukatzeko aukera duzu." - "Informazio gehiago lortzeko, joan %s aplikaziora." - "Hodeira kargatuko dira" - "Hodeira kargatuko dira, horretarako baimena berariaz ematen baduzu" - "Iragarleekin edo enpresekin partekatuko dira" - "Iragarleekin edo enpresekin partekatuko dira, horretarako baimena berariaz ematen baduzu" - "Dirua irabazteko erabiliko dira" - "Dirua irabazteko erabiliko dira, horretarako baimena berariaz ematen baduzu" - "Betiko gordeko eta analizatuko dira" - "Gorde eta analizatu egingo dira zuk zehazten duzun epean" - - %s astez gorde eta analizatuko dira - Astebetez gorde eta analizatuko dira - - "Aplikazioaren garatzaileak ez du zehaztu aplikazioak nola erabiltzen dituen datuak." "Aplikazioa erabiltzen ari zarenean soilik" "Ez zaio eman baimenik" "Ez zaio ukatu baimenik" @@ -205,10 +184,18 @@ "Musika aplikazioa" "Galeria aplikazioa" "Gidatze modua ezartzeko aplikazioa" - "Proxyaren bidez deiak egiteko aplikazioa" + + "Deiak iragazteko aplikazioa" "Deien aplikazio osagarria" - - + "Laguntza-aplikazioa" + "Autoan islatzeko aplikazioa" "Oharra: gailua berrabiarazten baduzu eta pantailaren blokeoa badaukazu ezarrita, ezingo da abiarazi aplikazioa gailua desblokeatzen duzun arte." + "Partekatu arazketa-datuak" + "Arazketa-datu xehatuak partekatu nahi dituzu?" + "%1$s aplikazioak arazketa-informazioa kargatu nahi du." + "Partekatu arazketa-datuak" + "%2$s datan (%3$s) sortutako akatsen txostena kargatzeko baimena eskatzen ari da %1$s. Akatsen txostenek zure gailuari buruzkoa den edo aplikazioek erregistratu duten informazio pertsonala dute; adibidez, erabiltzaile-izenak, kokapenari buruzko datuak, gailuaren identifikatzaileak eta sareari buruzko informazioa. Informazio hori izateko fidagarriak iruditzen zaizkizun pertsona eta aplikazioekin soilik partekatu beharko zenituzke akatsen txostenak. %4$s aplikazioari akatsen txostena kargatzea baimendu nahi diozu?" + "Baimendu" + "Ukatu" diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml index 3e34f9311..37dec7895 100644 --- a/res/values-fa/strings.xml +++ b/res/values-fa/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "پراستفاده‌ترین مجوزها در ۱۵ دقیقه گذشته" "پراستفاده‌ترین مجوزها در ۱ دقیقه گذشته" "برنامه‌ها" - - - - + "فیلترشده براساس: %1$s" + "حذف فیلتر" "فیلتر کردن براساس" "فیلتر کردن براساس مجوزها" "بیشترین مجوزها" "بیشترین تعداد دسترسی" "اخیر" - - + "بازخوانی" "استفاده از مجوزهای برنامه" "دسترسی: %1$s بار. کل مدت: %2$s. آخرین استفاده: %3$s قبل." "دسترسی: %1$s بار. آخرین استفاده: %2$s قبل." @@ -137,11 +134,9 @@ "%1$s %3$s پیش به %2$s دسترسی یافت." "%1$s به %2$s شما دسترسی پیدا نکرده است." "مشاهده استفاده از مجوزها با جزئیات" - - + "آخرین دسترسی: %1$s" "مجاز" - - + "مجاز فقط هنگام استفاده از برنامه" "رد شد" "مشاهده اطلاعات مصرف مفصل‌تر" @@ -165,22 +160,6 @@ "یادآوری‌های مجوز" "%s از مکانتان استفاده می‌کند" "این برنامه همیشه می‌تواند به مکانتان دسترسی داشته باشد. برای تغییر دادن، ضربه بزنید." - "برنامه‌نویس برنامه می‌گوید ممکن است داده‌هایتان به این صورت باشد:" - "اگر نحوه استفاده برنامه‌نویس برنامه از داده‌هایتان را دوست ندارید، می‌توانید مجوز را رد کنید." - "برای کسب اطلاعات بیشتر، به %s بروید." - "‏بارگذاری‌شده در cloud" - "‏بارگذاری‌شده در cloud وقتی صراحتاً آن را مجاز می‌کنید" - "هم‌رسانی‌شده با آگهی‌دهنده‌ها و کسب‌وکارها" - "هم‌رسانی‌شده با آگهی‌دهنده‌ها و کسب‌وکارها وقتی صراحتاً آن را مجاز می‌کنید" - "استفاده‌شده برای کسب درآمد" - "استفاده‌شده برای کسب درآمد وقتی صراحتاً آن را مجاز می‌کنید" - "ذخیره‌شده و تجزیه‌وتحلیل‌شده برای همیشه" - "ذخیره‌شده و تجزیه‌وتحلیل‌شده برای مدت‌زمانی که مشخص کرده‌اید" - - ذخیره‌شده و تجزیه‌وتحلیل‌شده برای %s هفته - ذخیره‌شده و تجزیه‌وتحلیل‌شده برای %s هفته - - "برنامه‌نویس برنامه مشخص نکرده است برنامه چگونه از داده‌هایتان استفاده می‌کند." "تنها هنگام استفاده از برنامه" "هیچ مجوزی اعطا نشده است" "هیچ مجوزی رد نشد" @@ -205,10 +184,18 @@ "برنامه موسیقی" "برنامه گالری" "برنامه تلفن حالت خودرو" - "برنامه تماس‌ پراکسی" + + "برنامه غربالگری تماس" "برنامه همراه تماس" - - + "برنامه همیار" + "برنامه طرح سه‌بعدی خودرو" "توجه: اگر دستگاهتان را بازراه‌اندازی کنید و قفل صفحه تنظیم کرده باشید، تا قفل تلفن را باز نکنید، این برنامه نمی‌تواند شروع به کار کند." + "هم‌رسانی داده‌های اشکال‌زدایی" + "جزئیات داده‌های اشکال‌زدایی هم‌رسانی شود؟" + "%1$s می‌خواهد اطلاعات اشکال‌زدایی را بارگذاری کند." + "هم‌رسانی داده‌های اشکال‌زدایی" + "%1$s درخواست بارگذاری گزارش اشکالی را دارد که در %2$s ساعت %3$s در این دستگاه پیش آمده است. گزارش‌های اشکال شامل اطلاعات شخصی درباره دستگاه شما است یا اطلاعاتی که توسط برنامه‌ها گزارش شده است، برای مثال نام‌های کاربر، داده‌های مکان، شناسه‌های دستگاه و اطلاعات شبکه. گزارش‌های اشکال را تنها با افراد و برنامه‌هایی هم‌رسانی کنید که به آن‌ها در این‌باره اعتماد دارید. به %4$s اجازه بارگذاری گزارش اشکال داده شود؟" + "مجاز" + "رد کردن" diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml index 43e6e69c9..afb587423 100644 --- a/res/values-fi/strings.xml +++ b/res/values-fi/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "Yleisimmät käyttöoikeudet viimeisten 15 min ajalta" "Yleisimmät käyttöoikeudet viimeisen minuutin ajalta" "Sovell." - - - - + "Suodatusperuste: %1$s" + "Poista suodatin" "Suodatusperuste" "Suodata käyttöoikeuksien perusteella" "Eniten käyttöoikeuksia" "Eniten käyttöoikeuksia" "Viimeisimmät" - - + "Päivitä" "Sovelluksen käyttöoikeudet" "Käyttö: %1$s kertaa. Kokonaiskesto: %2$s. Käytetty viimeksi %3$s sitten." "Käyttö: %1$s kertaa. Käytetty viimeksi %2$s sitten." @@ -137,11 +134,9 @@ "%2$s oli sovelluksen (%1$s) käytössä %3$s sitten" "%1$s ei ole käyttänyt kohdetta %2$s." "Näytä tarkat käyttöoikeustiedot" - - + "Viimeinen käyttökerta: %1$s" "Sallittu" - - + "Sallittu vain käytön aikana" "Kielletty" "Katso tarkat käyttötiedot" @@ -165,22 +160,6 @@ "Käyttölupamuistutukset" "%s on käyttänyt sijaintiasi" "Tämä sovellus voi aina käyttää sijaintiasi. Muuta napauttamalla." - "Sovelluskehittäjän mukaan dataasi saatetaan" - "Jos et pidä tämän kehittäjän datankäyttötavoista, voit kieltää käyttöoikeuden." - "Avaa %s, niin näet lisätietoja" - "ladata pilveen" - "ladata pilveen, kun sallit sen erikseen" - "jakaa mainostajille tai yrityksille" - "jakaa mainostajille tai yrityksille, kun sallit sen erikseen" - "käyttää tulouttamiseen" - "käyttää tulouttamiseen, kun sallit sen erikseen" - "tallentaa ja analysoida pysyvästi" - "tallentaa ja analysoida määrittämäsi ajan verran" - - tallentaa ja analysoida %s viikon ajan - tallentaa ja analysoida viikon ajan - - "Sovelluskehittäjä ei tarkentanut, miten sovellus käyttää dataasi." "Vain, kun sovellusta käytetään" "Käyttöoikeuksia ei ole myönnetty" "Ei estettyjä käyttöoikeuksia" @@ -205,10 +184,18 @@ "Musiikkisovellus" "Galleriasovellus" "Autotilan puhelinsovellus" - "Puhelujen välityssovellus" + + "Puhelujen suodatussovellus" "Puhelujen kumppanisovellus" - - + "Avustajasovellus" + "Auton heijastussovellus" "Huomaa: Jos käynnistät laitteen uudelleen ja näytön lukitus on käytössä, sovellus voi käynnistyä vasta avattuasi lukituksen." + "Jaa virheenkorjaustietoja" + "Jaetaanko yksityiskohtaisia virheenkorjaustietoja?" + "%1$s haluaa ladata virheenkorjaustietoja palvelimelle." + "Jaa virheenkorjaustietoja" + "%1$s pyytää saada ladata laitteelta virheraportin, joka luotiin %2$s kello %3$s. Virheraportit sisältävät yksityisiä laitetietoja ja sovellusten kirjaamia tietoja, esimerkiksi käyttäjänimiä, sijaintitietoja, laitteen tunnistetietoja ja verkkotietoja. Jaa virheraportteja vain ihmisille ja sovelluksille, joiden tietojen käsittelyyn luotat. Saako %4$s lähettää virheraportin?" + "Salli" + "Estä" diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml index 4541ce74a..e386d653e 100644 --- a/res/values-fr-rCA/strings.xml +++ b/res/values-fr-rCA/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "Util. d\'autor. les plus pop. dans les 15 dern. min." "Util. d\'autor. les plus popul. dans la dern. minute" "Applis" - - - - + "Filtré par : %1$s" + "Supprimer le filtre" "Filtrer par" "Filtrer par autorisation" "Le plus d\'autorisations" "Le plus d\'accès" "Récents" - - + "Actualiser" "Util. des autoris. de l\'appli" "Accès : %1$s fois. Durée totale : %2$s. Dernière utilisation : il y a %3$s." "Accès : %1$s fois. Dernière utilisation : il y a %2$s." @@ -137,11 +134,9 @@ "%1$s a accédé à votre %2$s il y a %3$s." "%1$s n\'a pas accédé à votre %2$s." "Afficher les autorisations d\'utilisation détaillées" - - + "Dernier accès : %1$s" "Autorisée" - - + "Autorisée seulement durant l\'utilisation" "Refusé" "Afficher les détails d\'utilisation" @@ -165,22 +160,6 @@ "Rappels d\'autorisation" "%s utilise l\'accès à votre position" "Cette application peut toujours accéder à votre position. Touchez l\'écran pour modifier cela." - "Le concepteur de l\'application a indiqué que vos données pourrait être :" - "Si vous n\'aimez pas la manière dont ce concepteur utilise vos données, vous pouvez refuser d\'accorder l\'autorisation." - "Accéder à %s pour en savoir plus." - "Téléversées vers le nuage" - "Téléversées vers le nuage lorsque vous l\'autorisez explicitement" - "Partagées avec les annonceurs ou les entreprises" - "Partagées avec les annonceurs ou les entreprises lorsque vous le définissez explicitement" - "Utilisée pour la monétisation" - "Utilisées pour la monétisation lorsque vous l\'autorisez explicitement" - "Enregistrées et analysées pour toujours" - "Enregistrées et analysées pour une durée que vous spécifiez" - - Enregistrées et analysées pendant %s semaine - Enregistrées et analysées pendant %s semai​nes - - "Le concepteur de l\'application n\'a pas indiqué comment celle-ci utilise vos données." "Uniquement lorsque l\'application est en cours d\'utilisation" "Aucune autorisation accordée" "Aucune autorisation refusée" @@ -205,10 +184,18 @@ "Application de musique" "Application de galerie" "Appli tél. pour mode Voiture" - "Appli d\'appels mandataires" + + "Appli de filtrage des appels" "Application compagnon d\'appel" - - + "Application d\'assistance" + "Appli de projection automobile" "Remarque : Si vous redémarrez votre appareil et que vous avez défini un verrouillage de l\'écran, cette application ne pourra pas démarrer tant que vous n\'avez pas déverrouillé votre appareil" + "Partager les données de débogage" + "Partager des données de débogage détaillées?" + "%1$s souhaite téléverser des données de débogage." + "Partager les données de débogage" + "L\'application %1$s souhaite téléverser un rapport de bogue créé le %2$s à %3$s sur cet appareil. Les rapports de bogue contiennent des données personnelles relatives à votre appareil ou enregistrées par des applications, comme des noms d\'utilisateur, des données de localisation, des identifiants d\'appareils et des renseignements relatifs au réseau. Ne partagez les rapports de bogue qu\'avec des personnes et des applications que vous jugez fiables. Autoriser l\'application %4$s à téléverser un rapport de bogue?" + "Autoriser" + "Refuser" diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index 4646b2f43..dad62bd4a 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "Autorisations les plus utilisées (depuis 15 min)" "Autorisations les plus utilisées (dernière minute)" "Applis" - - - - + "Données filtrées par : %1$s" + "Supprimer le filtre" "Filtrer par" "Filtrer par autorisation" "Le plus d\'autorisations" "Le plus d\'accès" "Du plus récent au plus ancien" - - + "Actualiser" "Utilisation des autorisations" "Accès : %1$s fois. Durée totale : %2$s. Dernière utilisation il y a %3$s." "Accès : %1$s fois. Dernière utilisation il y a %2$s." @@ -137,11 +134,9 @@ "%1$s a accédé à votre/vos %2$s il y a %3$s." "%1$s n\'a pas accédé à votre %2$s." "Afficher l\'utilisation détaillée des autorisations" - - + "Dernier accès : %1$s" "Autorisées" - - + "Autorisées seulement pendant l\'utilisation" "Refusées" "Afficher l\'utilisation détaillée" @@ -165,22 +160,6 @@ "Rappels relatifs aux autorisations" "L\'application %s utilise votre position" "Cette application peut accéder en permanence à votre position. Appuyez dessus pour modifier cette autorisation." - "Le développeur de l\'application signale que vos données pourront être :" - "Si la manière dont le développeur de cette application compte utiliser vos données ne vous convient pas, vous pouvez refuser l\'autorisation." - "Accédez à %s pour obtenir plus d\'informations." - "Importées dans le cloud" - "Importées dans le cloud lorsque vous l\'autorisez de manière explicite" - "Partagées avec des annonceurs ou des entreprises" - "Partagées avec des annonceurs ou des entreprises lorsque vous l\'autorisez de manière explicite" - "Utilisées pour la monétisation" - "Utilisées pour la monétisation lorsque vous l\'autorisez de manière explicite" - "Enregistrées et analysées indéfiniment" - "Enregistrées et analysées pendant une période que vous déterminez" - - Enregistrées et analysées pendant %s semaine - Enregistrées et analysées pendant %s semaines - - "Le développeur de l\'application n\'a pas indiqué la manière dont vos données seront utilisées." "Seulement quand l\'application est en cours d\'utilisation" "Aucune autorisation accordée" "Aucune autorisation refusée" @@ -205,10 +184,18 @@ "Application Musique" "Application Galerie" "Appli téléphone mode Voiture" - "Application d\'appels proxy" + + "Appli de filtrage des appels" "Application d\'appels associée" - - + "Application d\'assistance" + "Appli Projection de la voiture" "Remarque : Si vous redémarrez votre appareil et que le verrouillage de l\'écran est activé, vous ne pouvez pas lancer cette application tant que vous n\'avez pas déverrouillé votre appareil." + "Partager les données de débogage" + "Partager les données de débogage détaillées ?" + "L\'application %1$s souhaite transférer des informations de débogage." + "Partager les données de débogage" + "L\'application %1$s souhaite transférer un rapport de bug créé le %2$s à %3$s depuis cet appareil. Les rapports de bug contiennent des informations personnelles relatives à votre appareil ou enregistrées par des applications, telles que des noms d\'utilisateur, des données de localisation, des identifiants d\'appareils et des informations relatives au réseau. Ne partagez les rapports de bug qu\'avec des personnes et des applications que vous estimez fiables. Autoriser l\'application %4$s à transférer un rapport de bug ?" + "Autoriser" + "Refuser" diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml index 80065723b..178840db4 100644 --- a/res/values-gl/strings.xml +++ b/res/values-gl/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "Uso de permisos máis comúns nos últimos 15 minutos" "Uso de permisos máis comúns no último minuto" "Apps" - - - - + "Vista filtrada por: %1$s" + "Quitar filtro" "Filtrar por" "Filtrar por permisos" "Máis permisos" "Máis accesos" "Accesos recentes" - - + "Actualizar" "Uso dos permisos da aplicación" "Acceso: %1$s veces. Duración total: %2$s. Utilizouse por última vez hai %3$s." "Acceso: %1$s veces. Utilizouse por última vez hai %2$s." @@ -137,11 +134,9 @@ "%1$s accedeu hai %3$s ao seguinte: %2$s." "A aplicación %1$s non ten acceso a %2$s." "Consulta os detalles sobre o uso dos permisos" - - + "Último acceso: %1$s" "Permiso concedido" - - + "Só se permiten mentres se utilizan" "Permiso denegado" "Ver uso detallado" @@ -165,22 +160,6 @@ "Recordatorios de permisos" "A aplicación %s estivo utilizando a túa localización" "Esta aplicación pode acceder sempre á túa localización. Toca para cambiar esta opción." - "O programador da aplicación indica que os teus datos poden:" - "Se non che gusta como utiliza o programador da aplicación os teus datos, podes rexeitar o permiso." - "Accede á aplicación %s para obter máis información." - "Cargase na nube" - "Cargarse na nube cando o permitas explicitamente" - "Compartirse cos anunciantes ou coas empresas" - "Compartirse cos anunciantes ou coas empresas cando o permitas explicitamente" - "Utilizarse para a obtención de ingresos" - "Utilizarse para a obtención de ingresos cando o permitas explicitamente" - "Gardarse e analizarse para sempre" - "Gardarse e analizarse durante o tempo que especifiques" - - Gardarse e analizarse durante %s semanas - Gardarse e analizarse durante 1 semana - - "O programador da aplicación non especificou como utiliza a aplicación os teus datos." "Só cando se estea utilizando a aplicación" "Non se concederon permisos" "Non se denegou ningún permiso" @@ -205,10 +184,18 @@ "Aplicación Música" "Aplicación Galería" "App de tel. do modo de cond." - "App de chamadas mediante proxy" + + "App de filtro de chamadas" "App complementaria de chamadas" - - + "Aplicación de asistencia" + "App de proxección do coche" "Nota: Se reinicias o dispositivo e definiches un bloqueo de pantalla, esta aplicación non se poderá iniciar ata que desbloquees o dispositivo." + "Compartir datos de depuración" + "Queres compartir datos detallados da depuración?" + "A aplicación %1$s quere cargar información de depuración." + "Compartir datos de depuración" + "A aplicación %1$s quere subir un informe de erros deste dispositivo, xerado o %2$s (%3$s). Os informes de erros inclúen información persoal sobre o dispositivo ou datos rexistrados polas aplicacións, como os nomes de usuario, os datos de localización, os identificadores do dispositivo e a información da rede. Comparte estes informes unicamente con persoas e aplicacións de confianza. Queres permitir que a aplicación %4$s cargue un informe de erros?" + "Permitir" + "Denegar" diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml index 255f9d973..3ed31f8ca 100644 --- a/res/values-gu/strings.xml +++ b/res/values-gu/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "છેલ્લી 15 મિનિટમાં પરવાનગીનો ટોચનો ઉપયોગ" "છેલ્લી 1 મિનિટમાં પરવાનગીનો ટોચનો ઉપયોગ" "ઍપ" - - - - + "આના અનુસાર ફિલ્ટર કર્યું: %1$s" + "ફિલ્ટર કાઢી નાખો" "આના અનુસાર ફિલ્ટર કરો" "પરવાનગીઓ અનુસાર ફિલ્ટર કરો" "સૌથી વધુ પરવાનગીઓ" "સૌથી વધુ ઍક્સેસ" "તાજેતરના" - - + "રિફ્રેશ કરો" "અ‍ૅપ પરવાનગીઓનો ઉપયોગ" "ઍક્સેસ આપો: %1$s વાર. કુલ અવધિ: %2$s. છેલ્લે %3$s પહેલાં ઉપયોગ કર્યો હતો." "ઍક્સેસ આપો: %1$s વાર. છેલ્લે %2$s પહેલાં ઉપયોગ કર્યો હતો." @@ -137,11 +134,9 @@ "%1$s દ્વારા તમારી %2$sને %3$s પહેલાં અ‍ૅક્સેસ કરવામાં આવી હતી." "%1$sએ તમારા %2$sનો ઍક્સેસ મેળવ્યો નથી." "પરવાનગીઓનો વિગતવાર ઉપયોગ જુઓ" - - + "છેલ્લે થયેલો ઍક્સેસ: %1$s" "મંજૂર" - - + "માત્ર ઉપયોગમાં હોય ત્યારે જ મંજૂરી છે" "નકારેલ" "વિગતવાર વપરાશ જુઓ" @@ -165,22 +160,6 @@ "મંજૂરીના રિમાઇન્ડર" "%s તમારા સ્થાનનો ઉપયોગ કરી રહી છે" "આ ઍપ હંમેશાં તમારા સ્થાનને ઍક્સેસ કરી શકે છે. ફેરફાર કરવા માટે ટૅપ કરો." - "ઍપ ડેવલપરના કહેવા પ્રમાણે તમારો ડેટા કદાચ:" - "આ ઍપ ડેવલપર તમારા ડેટાનો જે રીતે ઉપયોગ કરતા હોય તે જો તમને ન ગમે, તો તમે પરવાનગી નકારી શકો છો." - "વધુ માહિતી માટે %s પર જાઓ" - "ક્લાઉડ પર અપલોડ કરવા માટે" - "તમે જ્યારે ચોક્કસ મંજૂરી આપો ત્યારે ક્લાઉડ પર અપલોડ કરવા માટે" - "જાહેરાતકર્તાઓ અથવા વ્યવસાયો સાથે શેર કરવા માટે" - "તમે જ્યારે ચોક્કસ મંજૂરી આપો ત્યારે જાહેરાતકર્તાઓ અથવા વ્યવસાયો સાથે શેર કરવા માટે" - "કમાણી કરવાની પ્રક્રિયામાં ઉપયોગમાં લેવા માટે" - "તમે જ્યારે ચોક્કસ મંજૂરી આપો ત્યારે કમાણી કરવાની પ્રક્રિયામાં ઉપયોગમાં લેવા માટે" - "હંમેશાં માટે ડેટા સાચવવામાં અને તેનું વિશ્લેષણ કરવા માટે" - "તમે સ્પષ્ટપણે વર્ણવેલા સમયગાળા માટે ડેટાને સાચવવાની અને વિશ્લેષણ કરવાની પરવાનગી" - - %s અઠવાડિયા માટે ડેટાને સાચવવા અને વિશ્લેષણ કરવા માટે - %s અઠવાડિયા માટે ડેટાને સાચવવા અને વિશ્લેષણ કરવા માટે - - "ઍપ તમારા ડેટાનો કઈ રીતે ઉપયોગ કરશે તે વિશે ઍપ ડેવલપરે કોઈ સ્પષ્ટતા કરી નથી." "માત્ર ઍપ ઉપયોગમાં હોય ત્યારે જ" "કોઈ પરવાનગીઓની મંજૂરી નથી" "કોઈ પરવાનગીઓ નકારવામાં આવી નથી" @@ -205,10 +184,18 @@ "મ્યુઝિક ઍપ" "ગૅલેરી ઍપ" "કાર મોડ ફોન ઍપ" - "પ્રૉક્સી કૉલિંગ ઍપ" + + "કૉલ સ્ક્રીનિંગ ઍપ" "કૉલ સાથી ઍપ" - - + "સહાયક ઍપ્લિકેશન" + "કાર પ્રોજેક્શન ઍપ" "નોંધ: જો તમે તમારું ડિવાઇસ ફરીથી શરૂ કરો અને કોઈ સ્ક્રીન લૉક સેટ કરેલું હોય, તો જ્યાં સુધી તમે તમારું ડિવાઇસ અનલૉક નહીં કરો ત્યાં સુધી આ ઍપ શરૂ થઈ શકશે નહીં." + "ડિબગીંગ ડેટા શેર કરો" + "વિગતવાર ડિબગીંગ ડેટા શેર કરીએ?" + "%1$s, ડિબગીંગ માહિતી અપલોડ કરવા માગે છે" + "ડિબગીંગ ડેટા શેર કરો" + "%1$s આ ડિવાઇસથી %2$sના રોજ %3$s વાગ્યે લેવામાં આવેલ ખામીની જાણકારી અપલોડ કરવાની મંજૂરી માગી રહી છે. ખામીની જાણકારીમાં તમારા ડિવાઇસ વિશે અથવા ઍપ દ્વારા લૉગ કરવામાં આવેલી વ્યક્તિગત માહિતી શામેલ હોય છે, જેમ કે વપરાશકર્તાનું નામ, સ્થાન ડેટા, ડિવાઇસ ઓળખકર્તા અને નેટવર્કની માહિતી. ખામીની જાણકારીને માત્ર તેવા જ લોકો અને ઍપ સાથે શેર કરો કે જેની પર તમે માહિતી બાબતે વિશ્વાસ કરો છો. %4$sને ખામીની જાણકારી અપલોડ કરવાની મંજૂરી આપીએ?" + "મંજૂરી આપો" + "નકારો" diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml index ac6842f6f..5b17b304f 100644 --- a/res/values-hi/strings.xml +++ b/res/values-hi/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "पिछले 15 मिनट में सबसे ज़्यादा बार मांगी गई अनुमति" "पिछले एक मिनट में सबसे ज़्यादा बार मांगी गई अनुमति" "ऐप्लिकेशन" - - - - + "इससे फ़िल्टर किया गया: %1$s" + "फ़िल्टर हटाएं" "इसके मुताबिक फ़िल्टर करें" "अनुमतियों के हिसाब से फ़िल्टर करें" "सबसे ज़्यादा ली गईं अनुमतियां" "सबसे ज़्यादा बार किए गए एक्सेस" "हाल ही में" - - + "रीफ़्रेश करें" "ऐप्लिकेशन अनुमतियों इस्तेमाल" "एक्सेस: %1$s बार. कुल अवधि: %2$s. आखिरी बार %3$s पहले इस्तेमाल किया गया." "एक्सेस: %1$s बार. आखिरी बार %2$s पहले इस्तेमाल किया गया." @@ -137,11 +134,9 @@ "%1$s ने %3$s पहले आपकी %2$s का इस्तेमाल किया है." "%1$s ने आपसे %2$s नहीं ली है." "अनुमतियों के इस्तेमाल से जुड़ी ज़्यादा जानकारी देखें" - - + "पिछली बार एक्सेस किया गया: %1$s" "अनुमति है" - - + "सिर्फ़ इस्तेमाल में होने पर अनुमति है" "मंज़ूरी नहीं मिली" "इस्तेमाल की ज़्यादा जानकारी देखें" @@ -165,22 +160,6 @@ "अनुमति रिमाइंडर" "%s आपकी जगह की जानकारी का इस्तेमाल कर रहा है" "यह ऐप्लिकेशन हमेशा आपकी जगह की जानकारी एक्सेस कर सकता है. बदलने के लिए टैप करें." - "ऐप्लिकेशन डेवलपर के हिसाब से आपका डेटा :" - "यह ऐप्लिकेशन डेवलपर आपके डेटा का जिस तरह से इस्तेमाल कर रहा है, अगर आपको वह तरीका पसंद नहीं है, तो अनुमति देने से मना कर सकते हैं." - "ज़्यादा जानकारी के लिए %s पर जाएं." - "क्लाउड पर अपलोड किया जा सकता है" - "साफ़ तौर पर आपकी अनुमति मिलने पर, क्लाउड पर अपलोड किया जा सकता है" - "विज्ञापनदाताओं या कारोबारियों के साथ शेयर किया जा सकता है" - "साफ़ तौर पर आपकी अनुमति मिलने पर, विज्ञापनदाताओं या कारोबारियों के साथ शेयर किया जा सकता है" - "कमाई करने के लिए इस्तेमाल किया जा सकता है" - "साफ़ तौर पर आपकी अनुमति मिलने पर, कमाई किए जाने के लिए इसका इस्तेमाल किया जा सकता है" - "हमेशा के लिए सेव किया जा सकता है और आंकड़े निकाले जा सकते हैं" - "आपके बताए गए समय तक के लिए सेव किया जा सकता है और आंकड़े निकाले जा सकते हैं" - - %s हफ़्ते के लिए सेव किया जा सकता है और आंकड़े निकाले जा सकते हैं - %s हफ़्तों के लिए सेव किया जा सकता है और आंकड़े निकाले जा सकते हैं - - "ऐप्लिकेशन डेवलपर ने यह नहीं बताया कि ऐप्लिकेशन किस तरह से आपके डेटा का इस्तेमाल करता है." "सिर्फ़ ऐप्लिकेशन इस्तेमाल में होने के दौरान" "कोई अनुमति नहीं मिली है" "सभी अनुमतियां मंज़ूर की गई हैं" @@ -205,10 +184,18 @@ "संगीत ऐप्लिकेशन" "गैलरी ऐप्लिकेशन" "कार मोड वाला फ़ोन ऐप्लिकेशन" - "प्रॉक्सी कॉलिंग ऐप्लिकेशन" + + "कॉल की स्क्रीनिंग का ऐप्लिकेशन" "कॉल करने का साथी ऐप्लिकेशन" - - + "सहायक ऐप्लिकेशन" + "कार प्रोजेक्शन ऐप्लिकेशन" "ध्यान दें : अगर डिवाइस को रीस्टार्ट करते समय उसकी स्क्रीन लॉक है, तो यह ऐप्लिकेशन तब तक शुरू नहीं होगा, जब तक आप डिवाइस को अनलॉक नहीं करते." + "डीबग करने की प्रक्रिया का डेटा शेयर करें" + "डीबग करने की ज़्यादा जानकारी शेयर करना चाहते हैं?" + "%1$s डीबग करने की जानकारी अपलोड करना चाहता है." + "डीबग करने की प्रक्रिया का डेटा शेयर करें" + "%1$s इस डिवाइस से %2$s को %3$s बजे ली गई गड़बड़ी की रिपोर्ट अपलोड करने की मंज़ूरी मांग रहा है. गड़बड़ी की रिपोर्ट में आपके डिवाइस के बारे में या ऐप्लिकेशन की ओर से लॉग की गई निजी जानकारी शामिल होती है, जैसे कि उपयोगकर्ता नाम, जगह की जानकारी का डेटा, डिवाइस पहचानकर्ता, और नेटवर्क की जानकारी. गड़बड़ी की रिपोर्ट सिर्फ़ उन लोगों और ऐप्लिकेशन के साथ शेयर करें जिन पर आप इस जानकारी को लेकर भरोसा करते हैं. क्या आप %4$s को गड़बड़ी की रिपोर्ट अपलोड करने देना चाहते हैं?" + "अनुमति दें" + "अनुमति न दें" diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml index 8ffd299f1..4bd137834 100644 --- a/res/values-hr/strings.xml +++ b/res/values-hr/strings.xml @@ -4,9 +4,9 @@ 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. @@ -115,17 +115,14 @@ "Upotreba dopuštenja u posljednjih 15 minuta" "Upotreba dopuštenja u posljednjoj minuti" "Aplikacije" - - - - + "Filtrirano po: %1$s" + "Ukloni filtar" "Kriterij filtriranja" "Filtriraj prema dopuštenjima" "Najviše dopuštenja" "Najviše pristupa" "Nedavno" - - + "Osvježi" "Upotreba dopuštenja aplikacije" "Pristup: %1$s puta. Ukupno trajanje: %2$s. Posljednji put korišteno prije %3$s." "Pristup: %1$s puta. Posljednji put korišteno prije %2$s." @@ -138,11 +135,9 @@ "Aplikacija %1$s pristupila je dopuštenju %2$s prije %3$s." "Aplikacija %1$s nije pristupila vašem dopuštenju %2$s." "Pregledajte detaljnu upotrebu dopuštenja" - - + "Zadnji pristup: %1$s" "Dopušteno" - - + "Dopušteno samo tijekom upotrebe" "Odbijeno" "Pogledajte detaljnu upotrebu" @@ -170,23 +165,6 @@ "Podsjetnici za dopuštenja" "Aplikacija %s koristi vašu lokaciju" "Ova aplikacija može uvijek pristupiti vašoj lokaciji. Dodirnite za promjenu." - "Razvojni programer aplikacije kaže da se vaši podaci mogu:" - "Ako vam se ne sviđa način na koji razvojni programer aplikacije upotrebljava vaše podatke, možete odbiti dopuštenje." - "Više informacija možete pronaći u aplikaciji %s." - "prenositi u oblak" - "prenositi u oblak kad to izričito dopustite" - "dijeliti s oglašivačima ili tvrtkama" - "dijeliti s oglašivačima ili tvrtkama kad to izričito dopustite" - "upotrebljavati za unovčavanje" - "upotrebljavati za unovčavanje kad to izričito dopustite" - "spremati i analizirati zauvijek" - "spremati i analizirati tijekom razdoblja koje navedete" - - spremati i analizirati​ %s tjedan - spremati i analizirati​ %s tjedna - spremati i analizirati​ %s tjedana - - "Razvojni programer aplikacije nije naveo kako aplikacija upotrebljava vaše podatke." "Samo dok je aplikacija u upotrebi" "Nije odobreno nijedno dopuštenje" "Nije odbijeno nijedno dopuštenje" @@ -211,10 +189,18 @@ "Aplikacija Glazba" "Aplikacija Galerija" "Ap. za način rada u automobilu" - "Aplikacija za proxy pozive" + + "Ap. za filtriranje poziva" "Popratna aplikacija za pozive" - - + "Aplikacija pomoćnik" + "Apl. Projekcija u automobilu" "Napomena: ako ponovo pokrenete uređaj, a na njemu je postavljeno zaključavanje zaslona, ova se aplikacija ne može pokrenuti dok ne otključate uređaj." + "Dijeli podatke o otklanjanju pogrešaka" + "Dijeliti detaljne podatke o otklanjanju pogrešaka?" + "%1$s želi prenijeti informacije o otklanjanju pogrešaka." + "Dijeli podatke o otklanjanju pogrešaka" + "%1$s zahtijeva prijenos izvješća o programskoj pogrešci s ovog uređaja od %2$s u %3$s. Izvješća o programskim pogreškama sadržavaju osobne podatke o uređaju ili one koje su zabilježile aplikacije, kao što su korisnička imena, podaci o lokaciji, alati za identifikaciju uređaja i podaci o mreži. Izvješća o programskim pogreškama dijelite samo s osobama i aplikacijama koje smatrate pouzdanima. Dopustiti aplikaciji %4$s prijenos izvješća o programskoj pogrešci?" + "Dopusti" + "Odbij" diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml index 4bea8c2f9..41984a807 100644 --- a/res/values-hu/strings.xml +++ b/res/values-hu/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "Leggyakoribb engedélyhasználat az előző 15 percben" "Leggyakoribb engedélyhasználat az elmúlt percben" "Alkalmazás" - - - - + "Szűrve a következő alapján: %1$s" + "Szűrő eltávolítása" "Szűrő:" "Szűrés engedélyek szerint" "Legtöbb engedély" "Legtöbb hozzáférés" "Legutóbbiak" - - + "Frissítés" "Alkalmazásengedély-használat" "Hozzáférés: %1$s alkalommal. Teljes időtartam: %2$s. Utoljára használva ennyi ideje: %3$s" "Hozzáférés: %1$s alkalommal. Utoljára használva ennyi ideje: %2$s" @@ -137,11 +134,9 @@ "A(z) %1$s alkalmazás hozzáfért a következőhöz: %2$s (ennyi ideje: %3$s)." "A(z) %1$s még nem fért hozzá a következő engedélyhez: %2$s." "Engedélyhasználat részletes adatainak megtekintése" - - + "Legutóbbi hozzáférés: %1$s" "Engedélyezett" - - + "Csak használat közben engedélyezett" "Elutasítva" "Részletes használati adatok megtekintése" @@ -165,22 +160,6 @@ "Engedélyekre vonatkozó emlékeztetők" "A(z) %s az Ön tartózkodási helyét használja" "Ez az alkalmazás bármikor hozzáférhet az Ön tartózkodási helyéhez. A módosításhoz koppintson." - "Az alkalmazás fejlesztője szerint az Ön adataival a következők történhetnek:" - "Ha nem tetszik, hogy az alkalmazás fejlesztője hogyan használja az Ön adatait, megtagadhatja az engedélyt." - "Ha további információt szeretne kapni, nyissa meg a(z) %s alkalmazást." - "Az alkalmazás feltöltheti őket a felhőbe" - "Az alkalmazás feltöltheti őket a felhőbe az Ön kifejezett engedélyével" - "Az alkalmazás megoszthatja őket hirdetőkkel vagy vállalkozásokkal" - "Az alkalmazás megoszthatja őket hirdetőkkel vagy vállalkozásokkal az Ön kifejezett engedélyével" - "A fejlesztő bevételszerzésre használhatja őket" - "Az alkalmazás bevételszerzésre használhatja őket az Ön kifejezett engedélyével" - "Az alkalmazás örökre mentheti és elemezheti őket" - "Az alkalmazás menti és elemzi őket az Ön által megadott ideig" - - Az alkalmazás menti és elemzi őket %s hétig - Az alkalmazás menti és elemzi őket 1 hétig - - "Az alkalmazás fejlesztője nem adta meg, hogy az alkalmazás hogyan használja a felhasználók adatait." "Csak az alkalmazás használata közben" "Nincs megadott engedély" "Nincs megtagadott engedély" @@ -205,10 +184,18 @@ "Zenealkalmazás" "Galériaalkalmazás" "Telefonalkalmazás autós módhoz" - "Proxyhívó alkalamazás" + + "Hívásszűrő alkalmazás" "Társalkalmazás hívásokhoz" - - + "Segédalkalmazás" + "Autós kivetítő alkalmazás" "Megjegyzés: Ha újraindítja az eszközt, és képernyőzárat állított be, ez az alkalmazás csak a telefon feloldását követően indul el." + "Hibakeresési adatok megosztása" + "Megosztja a részletes hibakeresési adatokat?" + "A(z) %1$s hibakeresési adatokat szeretne feltölteni." + "Hibakeresési adatok megosztása" + "A(z) %1$s hibajelentést szeretne feltölteni az eszközről (a jelentés létrehozásának időpontja: %2$s, %3$s). A hibajelentések eszközre vonatkozó vagy alkalmazások által rögzített személyes adatokat tartalmazhatnak, például felhasználóneveket, helyadatokat, eszközazonosítókat és hálózati adatokat. Csak megbízható személyekkel és alkalmazásokkal osszon meg hibajelentéseket. Engedélyezi, hogy a(z) %4$s hibajelentést töltsön fel?" + "Engedélyezés" + "Elutasítás" diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml index 23c2cc51b..7255a7012 100644 --- a/res/values-hy/strings.xml +++ b/res/values-hy/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "Ամենաօգտագործված թույլտվությունները վերջին 15 ր-ում" "Ամենաօգտագործված թույլտվությունները վերջին րոպեում" "Հավելվածներ" - - - - + "Զտված է ըստ՝ %1$s" + "Հեռացնել զտիչը" "Զտել ըստ" "Զտել ըստ թույլտվությունների" "Ամենաշատ օգտագործում" "Թույլտվությունների քանակ" "Վերջինները" - - + "Թարմացնել" "Թույլտվությունների օգտագործում" "Օգտագործվել է %1$s անգամ։ Ընդհանուր տևողությունը՝ %2$s։ Վերջին անգամ օգտագործվել է %3$s առաջ։" "Օգտագործվել է %1$s անգամ։ Վերջինը՝ %2$s առաջ։" @@ -137,11 +134,9 @@ "%1$s հավելվածը ստացել է «%2$s» թույլտվությունը %3$s առաջ:" "%1$s հավելվածին հասանելի չէ ձեր %2$sը:" "Դիտել թույլտվությունների օգտագործման մանրամասները" - - + "Վերջին օգտագործումը՝ %1$s" "Թույլատրված" - - + "Միայն հավելվածն օգտագործելիս" "Մերժված" "Դիտեք օգտագործման մանրամասները" @@ -165,22 +160,6 @@ "Հիշեցումներ թույլտվությունների մասին" %s» հավելվածն օգտագործում է ձեր տեղադրության մասին տվյալները" "Այս հավելվածին միշտ հասանելի են ձեր տեղադրության մասին տվյալները: Փոխելու համար հպեք:" - "Հավելվածի մշակողն ասում է, որ ձեր տվյալները կարող են՝" - "Եթե ձեզ դուր չի գալիս, թե ինչպես է հավելվածի մշակողն օգտագործում ձեր տվյալները, դուք կարող եք հեռացնել թույլտվությունը:" - "Լրացուցիչ տեղեկությունների համար անցեք %s:" - "Վերբեռնվել ամպ" - "Վերբեռնվել ամպ, երբ դա դուք բացահայտ թույլատրում եք" - "Տրամադրվել գովազդատուներին կամ ընկերություններին" - "Տրամադրվել գովազդատուներին կամ ընկերություններին, երբ դա դուք բացահայտ թույլատրում եք" - "Օգտագործվել դրամայնացման համար" - "Օգտագործվել դրամայնացման համար, երբ դա դուք բացահայտ թույլատրում եք" - "Պահվել և վերլուծվել ընդմիշտ" - "Պահվել և վերլուծվել այնքան ժամանակ, որքան դուք կնշեք" - - Պահվել և վերլուծվել %s շաբաթ - Պահվել և վերլուծվել %s շաբաթ - - "Հավելվածի մշակողը չի նշել, թե ինչպես է հավելվածը օգտագործում ձեր տվյալները:" "Միայն երբ հավելվածն օգտագործվում է" "Թույլտվությունները տրված չեն" "Բոլոր թույլտվությունները տրված են" @@ -205,10 +184,18 @@ "Երաժշտություն" "Ցուցասրահ" "«Հեռախոս» մեքենայի ռեժիմի համար" - "Հավելված պրոքսի զանգերի համար" + + "Հավելված զանգերի զտման համար" "Ուղեկցող հավելված զանգերի համար" - - + "Օգնական հավելված" + "Հեռարձակում մեքենայի էկրանին" "Ուշադրություն. եթե դուք վերագործարկեք ձեր սարքը, որում սահմանված է էկրանի կողպում, այս հավելվածը չի աշխատի, մինչև չապակողպեք սարքը։" + "Վրիպազերծման տվյալների ուղարկում" + "Ուղարկե՞լ վրիպազերծման մանրամասն տվյալները" + "%1$s-ն ուզում է վերբեռնել վրիպազերծման տվյալները:" + "Վրիպազերծման տվյալների ուղարկում" + "%1$s-ը թույլտվություն է խնդրում՝ այս սարքից վրիպակների հաշվետվությունը (վերցված %2$s-ին ժամը %3$s-ին) վերբեռնելու համար: Վրիպակների հաշվետվությունները ներառում են տվյալներ ձեր սարքի մասին կամ անձնական տվյալներ, որոնք գրանցվել են հավելվածների կողմից, օրինակ՝ օգտատերերի անուններ, տեղադրության մասին տվյալներ, սարքերի ID-ներ և ցանցի մասին տեղեկություններ: Վրիպակների հաշվետվություններով կիսվեք միայն այն մարդկանց ու հավելվածների հետ, որոնց կարող եք վստահել այս տեղեկությունները: Թույլատրե՞լ %4$s-ին վերբեռնել վրիպակների հաշվետվությունը:" + "Թույլատրել" + "Մերժել" diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml index 2848fb240..8d5631df2 100644 --- a/res/values-in/strings.xml +++ b/res/values-in/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "Penggunaan izin teratas dalam 15 menit terakhir" "Penggunaan izin teratas dalam 1 menit terakhir" "Aplikasi" - - - - + "Difilter menurut: %1$s" + "Hapus filter" "Filter menurut" "Filter menurut izin" "Izin terbanyak" "Paling banyak diakses" "Terbaru" - - + "Refresh" "Penggunaan izin aplikasi" "Akses: %1$s kali. Durasi total: %2$s. Terakhir digunakan %3$s yang lalu." "Akses: %1$s kali. Terakhir digunakan %2$s yang lalu." @@ -137,11 +134,9 @@ "%1$s mengakses %2$s Anda %3$s yang lalu." "%1$s belum mengakses %2$s Anda." "Melihat penggunaan izin mendetail" - - + "Akses terakhir: %1$s" "Diizinkan" - - + "Hanya diizinkan saat digunakan" "Ditolak" "Lihat penggunaan mendetail" @@ -165,22 +160,6 @@ "Pengingat izin" "%s sedang menggunakan lokasi Anda" "Aplikasi ini selalu dapat mengakses lokasi Anda. Tap untuk mengubah." - "Developer aplikasi mengatakan data Anda dapat:" - "Jika tidak menyukai cara developer aplikasi ini menggunakan data Anda, Anda dapat menolak izin." - "Buku %s untuk mengetahui informasi selengkapnya." - "Diupload ke cloud" - "Diupload ke cloud jika Anda secara tegas mengizinkannya" - "Dibagikan kepada pengiklan atau bisnis" - "Dibagikan kepada pengiklan atau bisnis jika Anda secara tegas mengizinkannya" - "Digunakan untuk monetisasi" - "Digunakan untuk monetisasi jika Anda secara tegas mengizinkannya" - "Disimpan dan dianalisis selamanya" - "Disimpan dan dianalisis selama durasi yang Anda tentukan" - - Disimpan dan dianalisis selama %s minggu - Disimpan dan dianalisis selama 1 minggu - - "Developer aplikasi tidak menentukan bagaimana aplikasi ini menggunakan data Anda." "Hanya saat aplikasi sedang digunakan" "Tidak ada izin" "Tidak ada izin yang ditolak" @@ -205,10 +184,18 @@ "Aplikasi Musik" "Aplikasi Galeri" "Aplikasi telepon mode mobil" - "Aplikasi panggilan proxy" + + "Aplikasi penyaringan telepon" "Aplikasi pendamping telepon" - - + "Aplikasi bantuan" + "Aplikasi Proyeksi Mobil" "Catatan: Jika Anda memulai ulang perangkat dan menyetel kunci layar, aplikasi ini tidak dapat dimulai hingga Anda membuka kunci perangkat Anda." + "Bagikan Data Proses Debug" + "Bagikan data proses debug yang mendetail?" + "%1$s ingin mengupload informasi proses debug." + "Bagikan Data Proses Debug" + "%1$s meminta untuk mengupload laporan bug dari perangkat ini yang diambil pada %2$s pukul %3$s. Laporan bug mencakup informasi pribadi tentang perangkat Anda atau yang dicatat dalam log oleh aplikasi, misalnya, nama pengguna, data lokasi, ID perangkat, dan informasi jaringan. Bagikan laporan bug hanya kepada orang dan aplikasi yang Anda percayai dengan informasi ini. Izinkan %4$s mengupload laporan bug?" + "Izinkan" + "Tolak" diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml index 9ce6a7cb5..d72890a7d 100644 --- a/res/values-is/strings.xml +++ b/res/values-is/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "Algengasta heimildanotkun síðustu 15 mínútur" "Algengasta heimildanotkun síðustu mínútu" "Forrit" - - - - + "Síað eftir: %1$s" + "Fjarlægja síu" "Sía eftir" "Sía eftir heimildum" "Flestar heimildir" "Mesta notkun" "Nýlegt" - - + "Endurnýja" "Notkun heimilda forrits" "Aðgangur: %1$s sinnum. Heildarlengd: %2$s. Síðast notað fyrir %3$s." "Aðgangur: %1$s sinnum. Síðast notað fyrir %2$s." @@ -137,11 +134,9 @@ "%1$s fékk aðgang að %2$s þínu fyrir %3$s." "%1$s hefur ekki fengið aðgang að %2$s." "Skoða nákvæma heimildanotkun" - - + "Síðast notuð: %1$s" "Leyft" - - + "Aðeins leyft við notkun" "Hafnað" "Sjá ítarlegar upplýsingar um notkun" @@ -165,22 +160,6 @@ "Áminningar um heimild" "%s hefur verið að nota staðsetningu þína" "Þetta forrit hefur alltaf aðgang að staðsetningu þinni. Ýttu til að breyta." - "Þróunaraðili forrits segir að gögnin þín kunni að vera:" - "Ef þér líkar ekki hvernig þessi þróunaraðili forrits notar gögnin þín geturðu hafnað heimildinni." - "Farðu í %s til að fá frekari upplýsingar." - "Hlaðið inn á skýið" - "Hlaðið inn á skýið þegar þú leyfir það sérstaklega" - "Deilt með auglýsendum eða fyrirtækjum" - "Deilt með auglýsendum eða fyrirtækjum þegar þú leyfir það sérstaklega" - "Notað fyrir tekjuöflun" - "Notað fyrir tekjuöflun þegar þú leyfir það sérstaklega" - "Vistað og greint til frambúðar" - "Vistað og greint í ákveðinn tíma sem þú tilgreindir" - - Vistað og greint í %s viku - Vistað og greint í %s vikur - - "Þróunaraðili forrits tilgreindi ekki hvernig forritið notar gögnin þín." "Aðeins þegar forritið er í notkun" "Engar heimildir leyfðar" "Engum heimildum hafnað" @@ -205,10 +184,18 @@ "Tónlistarforrit" "Myndasafnsforrit" "Símaforrit í bílastillingu" - "Proxy símtalaforrit" + + "Símtalasíuforrit" "Fylgiforrit fyrir símtöl" - - + "Aðstoðarforrit" + "Forrit fyrir vörpun bíls" "Athugaðu: Ef þú endurræsir tækið og það er með skjálás er ekki hægt að ræsa þetta forrit fyrr en þú tekur tækið úr lás." + "Deila villuleitargögnum" + "Viltu deila ítarlegum villuleitargögnum?" + "%1$s vill hlaða inn upplýsingum um villuleit." + "Deila villuleitargögnum" + "%1$s biður um að hlaða inn villutilkynningu úr þessu tæki frá %2$s kl. %3$s. Villutilkynningar innihalda persónuupplýsingar um tækið eða innskráningar forrita, til dæmis notendanöfn, staðsetningargögn, auðkenni tækis og upplýsingar um netkerfi. Deildu aðeins villutilkynningum með fólki og forritum sem þú treystir fyrir þessum upplýsingum. Leyfa %4$s að hlaða inn villutilkynningu?" + "Leyfa" + "Hafna" diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml index 4bccda447..98d6f614e 100644 --- a/res/values-it/strings.xml +++ b/res/values-it/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "Uso autorizzazioni principali, ultimi 15 minuti" "Uso autorizzazioni principali nell\'ultimo minuto" "App" - - - - + "Filtrata per: %1$s" + "Rimuovi filtro" "Filtra per" "Filtra per autorizzazioni" "Maggior numero autorizzazioni" "Maggior numero di accessi" "Recenti" - - + "Aggiorna" "Uso delle autorizzazioni app" "Accesso: %1$s volte. Durata totale: %2$s. Ultimo utilizzo: %3$s fa." "Accesso: %1$s volte. Ultimo utilizzo: %2$s fa." @@ -137,11 +134,9 @@ "L\'app %1$s ha avuto accesso ai tuoi dati di %2$s %3$s fa." "%1$s non ha accesso a %2$s." "Consulta l\'uso dettagliato delle autorizzazioni" - - + "Ultimo accesso: %1$s" "Consentite" - - + "Consentite solo durante l\'uso" "Rifiutate" "Vedi dati dettagliati sull\'utilizzo" @@ -165,22 +160,6 @@ "Promemoria autorizzazione" "L\'app %s sta usando la tua posizione" "Questa app può accedere sempre alla tua posizione. Tocca per modificare." - "Lo sviluppatore dell\'app dichiara che i tuoi dati potrebbero essere:" - "Se non gradisci il modo in cui lo sviluppatore dell\'app usa i tuoi dati, puoi negare l\'autorizzazione." - "Per ulteriori informazioni, apri l\'app %s." - "Caricati sulla cloud" - "Caricati sulla cloud con la tua autorizzazione esplicita" - "Condivisi con inserzionisti o attività" - "Condivisi con inserzionisti o attività con la tua autorizzazione esplicita" - "Usati per la monetizzazione" - "Usati per la monetizzazione con la tua autorizzazione esplicita" - "Memorizzati e analizzati per sempre" - "Memorizzati e analizzati per la durata di tempo da te specificata" - - Memorizzati e analizzati per %s settimane - Memorizzati e analizzati per 1 settimana - - "Lo sviluppatore dell\'app non ha indicato la modalità di utilizzo dei tuoi dati nell\'app." "Solo mentre l\'app è in uso" "Nessuna autorizzazione consentita" "Nessuna autorizzazione negata" @@ -205,10 +184,18 @@ "App per la musica" "App Galleria" "App telefono modalità auto" - "App per chiamate proxy" + + "App per screening chiamate" "App complementare chiamate" - - + "App di assistenza" + "App di proiezione dell\'auto" "Nota: se riavvii il dispositivo ed è impostato un blocco schermo, sarà possibile avviare l\'app soltanto dopo aver sbloccato il dispositivo." + "Condividi dati di debug" + "Condividere i dati di debug dettagliati?" + "L\'app %1$s vorrebbe caricare informazioni di debug." + "Condividi dati di debug" + "L\'app %1$s chiede di caricare una segnalazione di bug da questo dispositivo, ricevuta il giorno %2$s alle ore %3$s. Le segnalazioni di bug includono informazioni personali relative al tuo dispositivo oppure registrate dalle app, ad esempio nomi utente, dati sulla posizione, identificatori dei dispositivi e informazioni sulle reti. Condividi le segnalazioni di bug solo con persone e app che ritieni affidabili. Consentire all\'app %4$s di caricare una segnalazione di bug?" + "Consenti" + "Nega" diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml index b447b562d..05e057348 100644 --- a/res/values-iw/strings.xml +++ b/res/values-iw/strings.xml @@ -4,9 +4,9 @@ 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. @@ -116,17 +116,14 @@ "השימוש המוביל בהרשאות במהלך 15 הדקות האחרונות" "השימוש המוביל בהרשאות בדקה האחרונה" "אפליקציות" - - - - + "סינון לפי: %1$s" + "הסרת המסנן" "סינון לפי" "סינון לפי הרשאות" "הכי הרבה הרשאות" "הכי הרבה קבלות גישה" "מהזמן האחרון" - - + "רענון" "שימוש בהרשאות האפליקציה" "גישה: %1$s פעמים. משך זמן כולל: %2$s. שימוש אחרון לפני %3$s." "גישה: %1$s פעמים. שימוש אחרון לפני %2$s." @@ -139,11 +136,9 @@ "נעשתה גישה ל%2$s על ידי %1$s לפני %3$s." "לאפליקציה %1$s לא הייתה גישה אל %2$s." "הצגת שימוש מפורט בהרשאות" - - + "גישה אחרונה: %1$s" "יש הרשאה" - - + "מורשית רק בזמן שימוש" "אין הרשאה" "הצגת נתוני שימוש מפורטים בהרשאות" @@ -175,24 +170,6 @@ "תזכורות להרשאות" "נעשה שימוש במיקום שלך על ידי %s" "האפליקציה הזו יכולה תמיד לגשת למיקום שלך. יש להקיש כדי לשנות הגדרה זו." - "מפתח האפליקציה אומר שייתכן שהנתונים שלך:" - "אם אופן השימוש של מפתח האפליקציה בנתונים שלך לא מקובל עליך, ניתן להימנע ממתן ההרשאה." - "למידע נוסף יש לעבור אל %s." - "יועלו לענן" - "יועלו לענן כשיתקבל ממך אישור מפורש לכך" - "ישותפו עם מפרסמים או עסקים" - "ישותפו עם מפרסמים או עסקים כשיתקבל ממך אישור מפורש לכך" - "ישמשו למונטיזציה" - "ישמשו למונטיזציה כשיתקבל ממך אישור מפורש לכך" - "יישמרו וינותחו לנצח" - "יישמרו וינותחו למשך הזמן שיצוין" - - יישמרו וינותחו למשך %s שבועות - יישמרו וינותחו למשך %s שבועות - יישמרו וינותחו למשך %s שבועות - יישמרו וינותחו למשך שבוע אחד - - "מפתח האפליקציה לא ציין איזה שימוש נעשה בנתונים שלך על ידי האפליקציה." "רק בזמן שהאפליקציה בשימוש" "לא ניתנו הרשאות" "אין הרשאות שנדחו" @@ -217,10 +194,18 @@ "אפליקציית מוזיקה" "גלריית האפליקציות" "אפליקציית \'טלפון\' במצב נהיגה" - "‏אפליקציית שיחות באמצעות Proxy" + + "אפליקציה לסינון שיחות" "אפליקציה נלווית לשיחות" - - + "אפליקציית עזרה" + "אפליקציית ההקרנה של הרכב" "הערה: אם ביצעת הפעלה מחדש למכשיר ונעילת המסך מוגדרת, ניתן יהיה להפעיל את האפליקציה הזו רק לאחר ביטול נעילת המכשיר." + "שיתוף נתונים של ניפוי באגים" + "לשתף נתונים מפורטים של ניפוי באגים?" + "האפליקציה %1$s מבקשת להעלות נתונים של ניפוי באגים." + "שיתוף נתונים של ניפוי באגים" + "%1$s מבקשת להעלות דוח על באגים ממכשיר זה, שנוצר בתאריך %2$s בשעה %3$s. דוחות על באגים כוללים מידע אישי על המכשיר או מידע אישי שנשמר באמצעות אפליקציות. למשל, שמות משתמשים, נתוני מיקום, מזהי מכשיר ופרטי רשת. יש לשתף דוחות על באגים רק עם אנשים ואפליקציות מהימנים. לאפשר לאפליקציה %4$s להעלות דוח על באגים?" + "כן, זה בסדר" + "אני לא מרשה" diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml index 6ebfcd1d1..2b3d711d8 100644 --- a/res/values-ja/strings.xml +++ b/res/values-ja/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "使用頻度の高い権限(過去 15 分間)" "使用頻度の高い権限(過去 1 分間)" "アプリ" - - - - + "フィルタ: %1$s" + "フィルタを削除" "フィルタ条件" "権限で絞り込む" "権限数の多い順" "アクセス数の多い順" "最近" - - + "更新" "アプリの権限の使用" "アクセス: %1$s 回。合計時間: %2$s。前回の使用: %3$s前。" "アクセス: %1$s 回。前回の使用: %2$s前。" @@ -137,11 +134,9 @@ "%1$s%3$s前に%2$sにアクセスしました。" "%1$s はユーザーの%2$sにはアクセスしていません。" "権限の使用に関する詳細を表示" - - + "前回のアクセス: %1$s" "許可" - - + "使用中のみ許可" "拒否" "詳細な使用状況を表示" @@ -165,22 +160,6 @@ "権限のリマインダー" "%s は位置情報を使用しています" "このアプリは常に位置情報にアクセスできます。設定を変更するにはタップしてください。" - "アプリのデベロッパーは、以下の方法でユーザーデータを使用する可能性があります。" - "このアプリのデベロッパーにユーザーデータの使用を許可したくない場合は拒否してください。" - "詳細については、%s にアクセスしてください" - "クラウドにアップロードする" - "明示的に許可するとデータがクラウドにアップロードされます" - "広告主や企業に提供する" - "明示的に許可するとデータが広告主や企業に提供されます" - "収益化に使用する" - "明示的に許可するとデータが収益化に使用されます" - "保存と分析を無期限で行う" - "保存と分析を、ユーザーが指定した期間行う" - - 保存と分析を %s 週間行う - 保存と分析を 1 週間行う - - "アプリのデベロッパーは、ユーザーデータをどのように使用するかを明確にしていません。" "アプリが使用中の場合のみ" "許可されている権限はありません" "許可されていない権限はありません" @@ -205,10 +184,18 @@ "音楽アプリ" "ギャラリー アプリ" "運転モード電話アプリ" - "プロキシ呼び出しアプリ" + + "通話スクリーニング アプリ" "通話コンパニオン アプリ" - - + "アシストアプリ" + "車での投影アプリ" "注: デバイスを再起動したときに画面ロックが設定されている場合は、デバイスのロックを解除するまでこのアプリを起動できません。" + "デバッグデータの共有" + "詳細なデバッグデータを共有しますか?" + "%1$s がデバッグ情報のアップロードをリクエストしています。" + "デバッグデータの共有" + "%1$s が、%2$s%3$sにこのデバイスから取得したバグレポートのアップロードをリクエストしています。バグレポートには、ユーザー名、位置情報、デバイスの識別情報、ネットワーク情報など、デバイスに関する個人情報やアプリで記録された個人情報が含まれます。この情報を含むバグレポートは、信頼できる人やアプリとのみ共有してください。%4$s にバグレポートのアップロードを許可しますか?" + "許可" + "許可しない" diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml index fd5eaa50d..c09d834d1 100644 --- a/res/values-ka/strings.xml +++ b/res/values-ka/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "ხშირად გამოყენებული ნებართვები ბოლო 15 წუთში" "ხშირად გამოყენებული ნებართვები ბოლო 1 წუთში" "აპები" - - - - + "გაფილტვრის კრიტერიუმი: %1$s" + "ფილტრის გაუქმება" "გაფილტვრა კრიტერიუმით:" "გაფილტვრა ნებართვების მიხედვით" "ყველაზე მეტი ნებართვა" "ყველაზე მეტი წვდომა" "ბოლოდროინდელი" - - + "განახლება" "აპის ნებართვებით სარგებლობა" "წვდომა: %1$s-ჯერ. საერთო ხანგრძლივობა: %2$s. ბოლო გამოყენებიდან გავიდა %3$s." "წვდომა: %1$s-ჯერ. ბოლო გამოყენებიდან გავიდა %2$s." @@ -137,11 +134,9 @@ "%1$s-მა გამოიყენა თქვენი %2$s %3$sს წინ." "%1$s-ს არ გამოუყენებია თქვენი %2$s." "ნებართვების გამოყენების დეტალურად ნახვა" - - + "ბოლო წვდომა: %1$s" "დაშვებულია" - - + "დაშვებულია მხოლოდ გამოყენებისას" "უარყოფილია" "დეტალური გამოყენების ნახვა" @@ -165,22 +160,6 @@ "შეხსენებები ნებართვის შესახებ" "%s იყენებს თქვენს მდებარეობას" "ამ აპს ყოველთვის შეუძლია თქვენს მდებარეობაზე წვდომა. შეეხეთ შესაცვლელად." - "აპის დეველოპერის თქმით, თქვენი მონაცემები:" - "თუ აპის დეველოპერის მიერ თქვენი მონაცემების გამოყენების ხერხი არ მოგწონთ, შეგიძლიათ უარყოთ ნებართვა." - "დამატებითი ინფორმაციისთვის გადადით %s-ზე." - "აიტვირთება ღრუბელში" - "აიტვირთება ღრუბელში, თუ ეს საგანგებოდ არის დაშვებული თქვენ მიერ" - "ზიარდება რეკლამის განმთავსებლებთან ან დაწესებულებებთან" - "ზიარდება რეკლამის განმთავსებლებთან ან დაწესებულებებთან, თუ ეს საგანგებოდ არის დაშვებული თქვენ მიერ" - "გამოიყენება მონეტიზაციისთვის" - "გამოიყენება მონეტიზაციისთვის, თუ ეს საგანგებოდ არის დაშვებული თქვენ მიერ" - "შეინახება და გაანალიზდება სამუდამოდ" - "შეინახება და გაანალიზდება თქვენ მიერ მითითებული პერიოდის განმავლობაში" - - შეინახება და გაანალიზდება %s კვირის განმავლობაში - შეინახება და გაანალიზდება 1 კვირის განმავლობაში - - "აპის დეველოპერს არ მიუთითებია, როგორ მოხდება აპის მიერ თქვენი მონაცემების გამოყენება." "მხოლოდ აპის გამოყენებისას" "დაშვებული ნებართვები არ არის" "უარყოფილი ნებართვები არ არის" @@ -205,10 +184,18 @@ "მუსიკის აპი" "გალერეის აპი" "მანქანის რეჟიმის სატელეფ. აპი" - "პროქსი-დარეკვის აპი" + + "ზარების გაფილტვრის აპი" "დარეკვის კომპანიონი აპი" - - + "დამხმარე აპი" + "მანქანაში პროეცირების აპი" "შენიშვნა: თუ ეკრანის დაბლოკვის მეთოდს იყენებთ, მოწყობილობის გადატვირთვის შემდეგ ეს აპი ვერ გაეშვება, სანამ მოწყობილობას არ განბლოკავთ" + "გამართვის მონაცემების გაზიარება" + "გსურთ გამართვის დეტალური მონაცემების გაზიარება?" + "%1$s ითხოვს გამართვის ინფორმაციის ატვირთვას." + "გამართვის მონაცემების გაზიარება" + "%1$s ითხოვს ამ მოწყობილობიდან ხარვეზების ანგარიშის ატვირთვას, რომლის შექმნის თარიღია %2$s, %3$s. ხარვეზების ანგარიშები მოიცავს პერსონალურ ინფორმაციას თქვენი მოწყობილობის შესახებ ან აპების ჟურნალებში დაფიქსირებულ მონაცემებს, მაგალითად, მომხმარებლის სახელებს, მდებარეობის მონაცემებს, მოწყობილობების იდენტიფიკატორებსა და ქსელის ინფორმაციას. გირჩევთ, ხარვეზების ანგარიშები გაუზიაროთ მხოლოდ იმ ადამიანებსა და აპებს, რომლებსაც შეგიძლიათ ანდოთ ეს ინფორმაცია. გსურთ, %4$s-მა ატვირთოს ხარვეზების ანგარიში?" + "დაშვება" + "უარყოფა" diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml index 52b5e84a5..ee8dc870d 100644 --- a/res/values-kk/strings.xml +++ b/res/values-kk/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "Соңғы 15 минутта ең көп пайдаланылған рұқсат" "Соңғы 1 минутта ең көп пайдаланылған рұқсаттар" "Қолданба" - - - - + "Сүзгі шарты: %1$s" + "Сүзгіні өшіру" "Сүзгі параметрі:" "Рұқсаттар бойынша сүзу" "Ең көп пайдаланылған рұқсаттар" "Ең көп пайдаланылған кіру рұқсаттары" "Соңғы" - - + "Жаңарту" "Қолданба рұқсаттарын пайдалану" "Кіру рұқсаты сұралды: %1$s рет. Жалпы ұзақтығы: %2$s. Соңғы рет %3$s бұрын пайдаланылған." "Кіру рұқсаты сұралды: %1$s рет. Соңғы рет %2$s бұрын пайдаланылған." @@ -137,11 +134,9 @@ "%1$s қолданбасы %2$s рұқсатына %3$s бұрын кірді." "%1$s қолданбасы %2$s рұқсатын пайдаланбады." "Рұқсаттардың пайдаланылуы туралы мәліметтерді көру" - - + "Соңғы рет пайдаланылған уақыт: %1$s" "Берілген рұқсаттар" - - + "Қолданылып жатқанда ғана рұқсат етіледі" "Тыйым салынғандар" "Пайдалану туралы толығырақ көру" @@ -165,22 +160,6 @@ "Рұқсат туралы еске салғыштар" "%s қолданбасы геодерегіңізді пайдаланып келді" "Бұл қолданба геодерегіңізді кез келген уақытта пайдалана алады. Өзгерту үшін түртіңіз." - "Қолданба әзірлеушісі көрсеткендей, деректеріңіз келесідей болуы мүмкін:" - "Егер қолданба әзірлеушісінің деректерді пайдалану әдісі ұнамаса, рұқсат бермеуіңізге болады." - "Толығырақ ақпарат алу үшін %s қолданбасына кіріңіз." - "Бұлтқа жүктеп салынады" - "Айқын рұқсат берілген кезде, бұлтқа жүктеп салынады" - "Жарнама берушілермен немесе компаниялармен бөлісіледі" - "Айқын рұқсат берілген кезде, жарнама берушілермен немесе компаниялармен бөлісіледі" - "Монетизация үшін пайдаланылады" - "Айқын рұқсат берілген кезде, монетизация үшін пайдаланылады" - "Шексіз уақытқа сақталады және талданады" - "Сіз көрсеткен мерзім бойы сақталады және талданады" - - %s аптаға сақталады және талданады - 1 аптаға сақталады және талданады - - "Қолданба әзірлеушісі қолданбаның деректерді қалай пайдаланатынын көрсетпеген." "Қолданба пайдаланып жатқанда ғана" "Ешқандай рұқсат берілмеді" "Ешқандай рұқсатқа тыйым салынбады" @@ -205,10 +184,18 @@ "Музыка қолданбасы" "Галерея қолданбасы" "Көлік режиміндегі қоңырауларға арналған қолданба" - "Прокси-сервер қоңырауына арналған қолданба" + + "Қоңырауды тексеру қолданбасы" "Қоңырауға арналған қосымша қолданба" - - + "Көмекші қолданба" + "Көлік экранына шығару" "Ескертпе: Құрылғыңызды қайта қоссаңыз және экран құлыпталса, құрылғының құлпы ашылмайынша, қолданба іске қосылмайды." + "Түзету туралы деректерді бөлісу" + "Түзету туралы толығырақ деректер бөлісілсін бе?" + "%1$s қолданбасы түзету туралы ақпаратты жүктеп салғысы келеді." + "Түзету туралы деректерді бөлісу" + "%1$s қолданбасы осы құрылғыдан %2$s күні %3$s кезінде алынған қате туралы есепті жүктеп салуды сұрауда. Мұндай есептерге құрылғыңыз туралы немесе қолданбалар арқылы тіркелген жеке ақпарат (пайдаланушы аттары, геодерек, құрылғы идентификаторлары және желі туралы ақпарат) кіреді. Қате туралы есептерді тек сенімді адамдармен және қолданбалармен бөлісіңіз. %4$s қолданбасына қате туралы есепті жүктеп салуға рұқсат етілсін бе?" + "Рұқсат беру" + "Келіспеу" diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml index 6f30aa759..35b789e9b 100644 --- a/res/values-km/strings.xml +++ b/res/values-km/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "ការប្រើប្រាស់ការ​អនុញ្ញាតច្រើនបំផុតក្នុងរយៈពេល 15 នាទីចុងក្រោយ" "ការប្រើការអនុញ្ញាតច្រើនបំផុតរយៈពេល 1 នាទីចុងក្រោយ" "កម្មវិធី" - - - - + "ត្រង​តាម៖ %1$s" + "លុប​តម្រង" "ត្រងតាម" "ត្រង​តាមការ​អនុញ្ញាត" "ការ​អនុញ្ញាតច្រើនបំផុត" "ការចូលប្រើ​ច្រើនបំផុត" "ថ្មីៗ" - - + "ផ្ទុកឡើងវិញ" "ការប្រើប្រាស់​ការអនុញ្ញាត​កម្មវិធី" "ចូលប្រើ៖ %1$s ដង។ រយៈពេល​សរុប៖ %2$s។ បានប្រើចុងក្រោយ %3$s មុន។" "ចូលប្រើ៖ %1$s ដង។ បានប្រើចុងក្រោយ %2$s មុន។" @@ -137,11 +134,9 @@ "%1$s បាន​ចូលប្រើ %2$s របស់អ្នកកាលពី %3$s មុន។" "%1$s មិន​បាន​ចូលប្រើ %2$s របស់អ្នក​ទេ។" "មើល​ការ​ប្រើប្រាស់​ការអនុញ្ញាត​លម្អិត" - - + "ការចូលប្រើ​ចុងក្រោយ៖ %1$s" "បាន​អនុញ្ញាត" - - + "អនុញ្ញាត​ខណៈពេល​ប្រើប្រាស់តែ​ប៉ុណ្ណោះ" "បានបដិសេធ" "មើល​ការប្រើប្រាស់​លម្អិត" @@ -165,22 +160,6 @@ "ការរំលឹក​អំពី​ការអនុញ្ញាត" "%s បានប្រើប្រាស់​ទីតាំង​របស់អ្នក" "កម្មវិធី​នេះ​អាច​ចូលប្រើប្រាស់​ទីតាំង​របស់អ្នក​បានជា​និច្ច។ សូម​ចុច​ដើម្បី​ប្ដូរ។" - "អ្នក​អភិវឌ្ឍន៍​កម្មវិធី​និយាយ​ថា ទិន្នន័យរបស់អ្នក​អាច៖" - "ប្រសិនបើអ្នក​មិន​ពេញ​ចិត្ត​នឹងរបៀបដែល​អ្នក​អភិវឌ្ឍន៍​កម្មវិធី​កំពុង​ប្រើប្រាស់​ទិន្នន័យ​របស់អ្នក អ្នក​អាច​បដិសេធ​មិនឱ្យចូលប្រើ។" - "ចូលទៅ %s ដើម្បី​ទទួលបាន​ព័ត៍មាន​បន្ថែម។" - "​បង្ហោះ​ទៅក្នុង​ពពក" - "បង្ហោះ​ទៅក្នុង​ពពក នៅពេល​អ្នក​អនុញ្ញាត​ច្បាស់​លាស់" - "​ចែករំលែក​ជាមួយ​អ្នកផ្សាយពាណិជ្ជកម្ម ឬ​អាជីវកម្ម​ផ្សេងៗ" - "​ចែករំលែក​ជាមួយ​អ្នកផ្សាយពាណិជ្ជកម្ម ឬ​អាជីវកម្ម​ផ្សេងៗ នៅពេល​អ្នក​អនុញ្ញាត​ច្បាស់​លាស់" - "​ប្រើ​សម្រាប់​រកប្រាក់" - "ប្រើ​សម្រាប់​រកប្រាក់ នៅពេល​អ្នក​អនុញ្ញាត​ច្បាស់​លាស់" - "​រក្សា​ទុក និង​វិភាគ​ជារៀងរហូត" - "​រក្សាទុក និងវិភាគ​ក្នុងរយៈពេលដែលអ្នកបញ្ជាក់" - - ​រក្សាទុក និងវិភាគ​រយៈពេល %s សប្តាហ៍ - រក្សាទុក និងវិភាគ​រយៈពេល​ 1 សប្តាហ៍ - - "អ្នក​អភិវឌ្ឍន៍​កម្មវិធី​មិន​បាន​បញ្ជាក់ថា កម្មវិធី​ប្រើប្រាស់​ទិន្នន័យ​របស់អ្នករបៀប​ណា​ទេ។" "ពេល​កំពុង​ប្រើប្រាស់​កម្មវិធីតែ​ប៉ុណ្ណោះ" "មិន​បាន​ផ្ដល់ការអនុញ្ញាតទេ" "មិន​បានបដិសេធការ​អនុញ្ញាតទេ" @@ -205,10 +184,18 @@ "កម្មវិធី​តន្រី្ត" "កម្មវិធីសាល​រូបភាព" "កម្មវិធី​ទូរសព្ទ​នៃមុខងារ​រថយន្ត" - "ការហៅ​ទូរសព្ទ​តាមរយៈ​លេខ​តំណាង" + + "កម្មវិធីត្រួតពិនិត្យការហៅទូរសព្ទ" "កម្មវិធី​ដៃគូ​សម្រាប់​ហៅទូរសព្ទ" - - + "កម្មវិធី​ជំនួយ" + "កម្មវិធី​បញ្ចាំង​របស់​រថយន្ត" "ចំណាំ៖ ប្រសិនបើ​អ្នកចាប់ផ្ដើម​ឧបករណ៍​​របស់អ្នក​ឡើងវិញ និងបានកំណត់​ការចាក់សោ​អេក្រង់ កម្មវិធីនេះ​មិនអាច​ចាប់ផ្តើម​បានទេ រហូតទាល់តែ​អ្នកដោះសោ​ឧបករណ៍របស់អ្នក។" + "ចែករំលែក​ទិន្នន័យ​នៃការ​ជួសជុល" + "ចែករំលែក​ទិន្នន័យ​លម្អិត​នៃការជួសជុល?" + "%1$s ចង់​បង្ហោះ​ព័ត៌មាននៃ​ការជួសជុល។" + "ចែករំលែក​ទិន្នន័យ​នៃការ​ជួសជុល" + "%1$s កំពុង​ស្នើសុំ​បង្ហោះ​របាយការណ៍​អំពី​បញ្ហាពី​ឧបករណ៍​នេះ ដែល​បាន​ធ្វើឡើង​នៅថ្ងៃទី %2$s ម៉ោង %3$s។ របាយការណ៍​អំពី​បញ្ហា​រួមមាន​ព័ត៌មាន​អំពី​ឧបករណ៍​របស់អ្នក​ ឬព័ត៌មាន​ដែលបាន​កត់ត្រា​ដោយ​កម្មវិធី​ដូចជា ឈ្មោះ​អ្នកប្រើប្រាស់ ទិន្នន័យទីតាំង ព័ត៌មាន​សម្គាល់​ឧបករណ៍ និង​ព័ត៌មាន​បណ្ដាញ​ជាដើម។ ចែករំលែក​របាយការណ៍​អំពី​បញ្ហា​ជាមួយ​កម្មវិធី និង​មនុស្សដែល​អ្នកទុកចិត្ត​ប៉ុណ្ណោះ ពាក់ព័ន្ធនឹង​ព័ត៌មាន​នេះ។ អនុញ្ញាត​ឱ្យ %4$s បង្ហោះ​របាយការណ៍​អំពី​បញ្ហា?" + "អនុញ្ញាត" + "បដិសេធ" diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml index ccee1494f..91e8a6f29 100644 --- a/res/values-kn/strings.xml +++ b/res/values-kn/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "ಕಳೆದ 15 ನಿಮಿಷಗಳಲ್ಲಿ ಪ್ರಮುಖ ಅನುಮತಿಯ ಬಳಕೆ" "ಕಳೆದ 1 ನಿಮಿಷದಲ್ಲಿ ಪ್ರಮುಖ ಅನುಮತಿಯ ಬಳಕೆ" "ಆ್ಯಪ್‌ಗಳು" - - - - + "ಈ ಆಧಾರದ ಮೇಲೆ ಫಿಲ್ಟರ್ ಮಾಡಲಾಗಿದೆ: %1$s" + "ಫಿಲ್ಟರ್ ತೆಗೆದುಹಾಕಿ" "ಈ ಪ್ರಕಾರ ಫಿಲ್ಟರ್" "ಅನುಮತಿಗಳ ಮೂಲಕ ಫಿಲ್ಟರ್ ಮಾಡಿ" "ಹೆಚ್ಚಿನ ಅನುಮತಿಗಳು" "ಹೆಚ್ಚಿನ ಪ್ರವೇಶಗಳು" "ಇತ್ತೀಚಿನವು" - - + "ರಿಫ್ರೆಶ್ ಮಾಡಿ" "ಆ್ಯಪ್‌ ಅನುಮತಿಗಳ ಬಳಕೆ" "ಪ್ರವೇಶ: %1$s ಬಾರಿ. ಒಟ್ಟು ಅವಧಿ: %2$s. %3$s ಸಮಯದ ಹಿಂದೆ ಕೊನೆಯದಾಗಿ ಬಳಸಲಾಗಿದೆ." "ಪ್ರವೇಶ: %1$s ಬಾರಿ. %2$s ಸಮಯದ ಹಿಂದೆ ಕೊನೆಯದಾಗಿ ಬಳಸಲಾಗಿದೆ." @@ -137,11 +134,9 @@ "%1$s ಆ್ಯಪ್ ನಿಮ್ಮ %2$s ಅನ್ನು %3$s ಹಿಂದೆ ಪ್ರವೇಶಿಸಿದೆ." "%1$s ನಿಮ್ಮ %2$s ಅನ್ನು ಪ್ರವೇಶಿಸಿಲ್ಲ." "ವಿವರವಾದ ಅನುಮತಿಗಳ ಬಳಕೆಯನ್ನು ವೀಕ್ಷಿಸಿ" - - + "ಕೊನೆಯ ಪ್ರವೇಶ:%1$s" "ಅನುಮತಿಸಲಾಗಿದೆ" - - + "ಬಳಕೆಯಲ್ಲಿದ್ದಾಗ ಮಾತ್ರ ಅನುಮತಿಸಲಾಗಿದೆ" "ನಿರಾಕರಿಸಲಾಗಿದೆ" "ವಿವರಿಸಲಾದ ಬಳಕೆಯನ್ನು ನೋಡಿ" @@ -165,22 +160,6 @@ "ಅನುಮತಿ ಜ್ಞಾಪನೆಗಳು" "%s ನಿಮ್ಮ ಸ್ಥಳವನ್ನು ಬಳಸುತ್ತಿದೆ" "ಈ ಆ್ಯಪ್‌ ಯಾವಾಗಲೂ ನಿಮ್ಮ ಸ್ಥಳವನ್ನು ಪ್ರವೇಶಿಸಬಹುದು. ಬದಲಾಯಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ." - "ಆ್ಯಪ್ ಡೆವಲಪರ್ ಈ ರೀತಿಯಾಗಿ ಹೇಳುತ್ತಾರೆ ನಿಮ್ಮ ಡೇಟಾ ಈ ರೀತಿಯಾಗಿರಬಹುದು:" - "ಈ ಆ್ಯಪ್ ಡೆವಲಪರ್, ನಿಮ್ಮ ಡೇಟಾವನ್ನು ಬಳಸುವ ರೀತಿಯು ನಿಮಗೆ ಇಷ್ಟವಾಗದಿದ್ದಲ್ಲಿ, ನೀವು ಅನುಮತಿಯನ್ನು ನಿರಾಕರಿಸಬಹುದು." - "ಹೆಚ್ಚಿನ ಮಾಹಿತಿಗಾಗಿ %s ಗೆ ಹೋಗಿ." - "ಕ್ಲೌಡ್‌ಗೆ ಅಪ್‌ಲೋಡ್ ಮಾಡಲಾಗಿದೆ" - "ಡೇಟಾ ಅಪ್‌ಲೋಡ್ ಮಾಡುವುದನ್ನು ನೀವು ಸ್ಪಷ್ಟವಾಗಿ ಅನುಮತಿಸಿದಾಗ, ಇದನ್ನು ಕ್ಲೌಡ್‌ಗೆ ಅಪ್‌ಲೋಡ್ ಮಾಡಲಾಗಿದೆ" - "ಜಾಹೀರಾತುದಾರರು ಅಥವಾ ವ್ಯಾಪಾರಗಳ ಜೊತೆಗೆ ಹಂಚಿಕೊಳ್ಳಲಾಗಿದೆ" - "ಡೇಟಾ ಹಂಚಿಕೊಳ್ಳುವುದನ್ನು ನೀವು ಸ್ಪಷ್ಟವಾಗಿ ಅನುಮತಿಸಿದಾಗ, ಇದನ್ನು ಜಾಹೀರಾತುದಾರರು ಅಥವಾ ವ್ಯಾಪಾರಗಳ ಜೊತೆಗೆ ಹಂಚಿಕೊಳ್ಳಲಾಗಿದೆ" - "ಹಣ ಗಳಿಕೆಗಾಗಿ ಬಳಸಲಾಗಿದೆ" - "ಡೇಟಾ ಬಳಸುವುದನ್ನು ನೀವು ಸ್ಪಷ್ಟವಾಗಿ ಅನುಮತಿಸಿದಾಗ, ಇದನ್ನು ಹಣ ಗಳಿಕೆಗಾಗಿ ಬಳಸಲಾಗಿದೆ" - "ಶಾಶ್ವತವಾಗಿ ಉಳಿಸಲಾಗಿದೆ ಮತ್ತು ವಿಶ್ಲೇಷಿಸಲಾಗಿದೆ" - "ನೀವು ನಿರ್ದಿಷ್ಟಪಡಿಸಿದ ಅವಧಿಗಾಗಿ ಉಳಿಸಲಾಗಿದೆ ಮತ್ತು ವಿಶ್ಲೇಷಿಸಲಾಗಿದೆ" - - %s ವಾರಗಳವರೆಗೆ ಉಳಿಸಲಾಗಿದೆ ಮತ್ತು ವಿಶ್ಲೇಷಿಸಲಾಗಿದೆ - %s ವಾರಗಳವರೆಗೆ ಉಳಿಸಲಾಗಿದೆ ಮತ್ತು ವಿಶ್ಲೇಷಿಸಲಾಗಿದೆ - - "ಆ್ಯಪ್ ಹೇಗೆ ನಿಮ್ಮ ಡೇಟಾವನ್ನು ಬಳಸುತ್ತದೆ ಎಂಬುದನ್ನು ಆ್ಯಪ್ ಡೆವಲಪರ್ ನಿರ್ದಿಷ್ಟಪಡಿಸಿಲ್ಲ." "ಆ್ಯಪ್ ಬಳಕೆಯಲ್ಲಿದ್ದಾಗ ಮಾತ್ರ" "ಯಾವುದೇ ಅನುಮತಿಗಳನ್ನು ಅನುಮತಿಸಲಾಗಿಲ್ಲ" "ಯಾವುದೇ ಅನುಮತಿಗಳನ್ನು ನಿರಾಕರಿಸಲಾಗಿಲ್ಲ" @@ -205,10 +184,18 @@ "ಸಂಗೀತ ಆ್ಯಪ್‌" "ಗ್ಯಾಲರಿ ಆ್ಯಪ್‌" "ಕಾರ್‌ ಮೋಡ್‌ ಫೋನ್‌ ಆ್ಯಪ್" - "ಪ್ರಾಕ್ಸಿ ಕರೆ ಮಾಡುವಿಕೆ ಆ್ಯಪ್‌" + + "ಕರೆ ಸ್ಕ್ರೀನಿಂಗ್ ಆ್ಯಪ್" "ಕರೆ ಕಂಪ್ಯಾನಿಯನ್ ಆ್ಯಪ್" - - + "ಅಸಿಸ್ಟೆಂಟ್ ಆ್ಯಪ್‌" + "ಕಾರ್ ಪ್ರೊಜೆಕ್ಷನ್ ಆ್ಯಪ್‌" "ಗಮನಿಸಿ: ನೀವು ನಿಮ್ಮ ಸಾಧನವನ್ನು ಮರುಪ್ರಾರಂಭಿಸಿದಲ್ಲಿ ಮತ್ತು ಪರದೆಯ ಲಾಕ್‌ ಹೊಂದಿದ್ದರೆ, ನಿಮ್ಮ ಸಾಧನವನ್ನು ಅನ್‌ಲಾಕ್‌ ಮಾಡುವವರೆಗೂ ಈ ಆ್ಯಪ್‌ ಅನ್ನು ಪ್ರಾರಂಭಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ" + "ಡೀಬಗ್ ಮಾಡುವಿಕೆ ಡೇಟಾವನ್ನು ಹಂಚಿಕೊಳ್ಳಿ" + "ವಿವರವಾದ ಡೀಬಗ್ ಮಾಡುವಿಕೆಯ ಡೇಟಾವನ್ನು ಹಂಚಿಕೊಳ್ಳಬೇಕೆ?" + "%1$s ಆ್ಯಪ್, ಡೀಬಗ್ ಮಾಡುವಿಕೆಯ ಮಾಹಿತಿಯನ್ನು ಅಪ್‌ಲೋಡ್ ಮಾಡಲು ಬಯಸುತ್ತದೆ." + "ಡೀಬಗ್ ಮಾಡುವಿಕೆ ಡೇಟಾವನ್ನು ಹಂಚಿಕೊಳ್ಳಿ" + "%2$s ದಿನಾಂಕದಂದು %3$s ಸಮಯಕ್ಕೆ ತೆಗೆದುಕೊಂಡ ಬಗ್ ವರದಿಯನ್ನು ಈ ಸಾಧನದಿಂದ ಅಪ್‌ಲೋಡ್ ಮಾಡುವಂತೆ %1$s ಆ್ಯಪ್ ವಿನಂತಿಸುತ್ತಿದೆ. ಬಗ್ ವರದಿಗಳು, ನಿಮ್ಮ ಸಾಧನ ಅಥವಾ ಆ್ಯಪ್‌ಗಳ ಮೂಲಕ ಲಾಗ್ ಮಾಡಿದ ವೈಯಕ್ತಿಕ ಮಾಹಿತಿಯನ್ನು, ಉದಾಹರಣೆಗೆ ಬಳಕೆದಾರರ ಹೆಸರುಗಳು, ಸ್ಥಳದ ಡೇಟಾ, ಸಾಧನ ಗುರುತಿಸುವಿಕೆಗಳು ಮತ್ತು ನೆಟ್‌ವರ್ಕ್‌ ಮಾಹಿತಿಯನ್ನು ಒಳಗೊಂಡಿದೆ. ಈ ಮಾಹಿತಿ ಒಳಗೊಂಡಂತೆ, ನೀವು ನಂಬುವ ಜನರು ಮತ್ತು ಆ್ಯಪ್‌ಗಳ ಜೊತೆಗೆ ಮಾತ್ರ ಬಗ್ ವರದಿಗಳನ್ನು ಹಂಚಿಕೊಳ್ಳಿ. ಬಗ್ ವರದಿಯನ್ನು ಅಪ್‌ಲೋಡ್‌ ಮಾಡಲು %4$s ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸುವುದೇ?" + "ಅನುಮತಿಸಿ" + "ನಿರಾಕರಿಸಿ" diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml index 24084a48e..f84d91bb1 100644 --- a/res/values-ko/strings.xml +++ b/res/values-ko/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "지난 15분 동안 가장 많이 사용된 권한" "지난 1분 동안 가장 많이 사용된 권한" "앱" - - - - + "필터링 기준: %1$s" + "필터 삭제" "필터링 기준" "권한별로 필터링" "사용된 권한 수" "액세스 횟수" "최근" - - + "새로고침" "앱 권한 사용" "액세스: %1$s회, 총 기간: %2$s, 마지막 사용: %3$s 전" "액세스: %1$s회, 마지막 사용: %2$s 전" @@ -137,11 +134,9 @@ "%3$s 전에 %1$s 앱이 %2$s에 액세스했습니다." "%1$s 앱이 %2$s에 액세스하지 않았습니다." "자세한 권한 사용 내역 보기" - - + "마지막 액세스: %1$s" "허용됨" - - + "사용 중에만 허용됨" "거부됨" "자세한 사용량 보기" @@ -165,22 +160,6 @@ "권한 알림" "%s에서 내 위치를 사용함" "이 앱에서 내 위치에 항상 액세스할 수 있습니다. 변경하려면 탭하세요." - "앱 개발자에 따르면 데이터가 다음과 같이 사용될 수 있습니다" - "앱 개발자의 데이터 사용 방식이 마음에 들지 않으면 권한 요청을 거부할 수 있습니다." - "자세한 내용은 %s을(를) 방문하세요." - "클라우드에 업로드됨" - "사용자가 명시적으로 허용할 경우 클라우드에 업로드됨" - "광고주 또는 비즈니스와 공유됨" - "사용자가 명시적으로 허용할 경우 광고주 또는 비즈니스와 공유됨" - "수익 창출에 사용됨" - "사용자가 명시적으로 허용할 경우 수익 창출에 사용됨" - "영구적으로 저장 및 분석됨" - "사용자가 지정한 기간 동안 저장 및 분석됨" - - %s주 동안 저장 및 분석됨 - 1주 동안 저장 및 분석됨 - - "앱 개발자가 앱의 데이터 사용 방식을 명시하지 않았습니다." "앱 사용 중에만" "허용된 권한 없음" "거부된 권한 없음" @@ -205,10 +184,18 @@ "음악 앱" "갤러리 앱" "자동차 모드 전화 앱" - "프록시 통화 앱" + + "통화 선택 앱" "통화 호환 앱" - - + "지원 앱" + "차량 프로젝션 앱" "참고: 화면 잠금이 설정되어 있다면 기기를 다시 시작한 후 이 앱을 시작하려면 기기를 잠금 해제해야 합니다." + "디버깅 데이터 공유" + "상세한 디버깅 데이터를 공유하시겠습니까?" + "%1$s에서 디버깅 정보를 업로드하려고 합니다." + "디버깅 데이터 공유" + "%1$s이(가) 이 기기에서 %2$s %3$s에 만들어진 버그 신고를 업로드하려고 합니다. 버그 신고에는 기기에 관한 개인정보나 앱이 기록한 개인정보(예: 사용자 이름, 위치 데이터, 기기 식별자, 네트워크 정보)가 포함됩니다. 이 정보는 신뢰할 수 있는 사람 또는 앱에 한해 공유해야 합니다. %4$s에서 버그 신고를 업로드하도록 허용할까요?" + "허용" + "거부" diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml index 313822aa0..b06085dfb 100644 --- a/res/values-ky/strings.xml +++ b/res/values-ky/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "Акыркы 15 мүнөттө эң көп колдонулган уруксаттар" "Акыркы 1 мүнөттө эң көп колдонулган уруксаттар" "Колдонмолор" - - - - + "Төмөнкү боюнча чыпкаланды: %1$s" + "Чыпканы алып салуу" "Төмөнкү боюнча чыпкалоо:" "Уруксаттар боюнча чыпкалоо" "Эң көп колдонулган уруксаттар" "Эң көп колдонулган уруксаттар" "Акыркылар" - - + "Жаңыртуу" "Колдонмонун уруксаттарын пайдалануу" "Кирүү: %1$s жолу. Жалпы колдонулган убакыт: %2$s. Акыркы жолу %3$s колдонулган." "Кирүү: %1$s жолу. Акыркы жолу %2$s колдонулган." @@ -137,11 +134,9 @@ "%1$s %2$s дайындарыңызга %3$s мурун кирген." "%1$s %2$s уруксаттарыңызга кирген жок." "Уруксаттардын колдонулушун чоо-жайы менен көрүү" - - + "Акыркы жолу колдонулушу: %1$s" "Уруксат берилген" - - + "Колдонулган кезде гана уруксат" "Четке кагылды" "Бардык уруксаттардын колдонулушун көрүү" @@ -165,22 +160,6 @@ "Уруксат жөнүндө эстеткичтер" "%s кайда жүргөнүңүз тууралуу маалыматты колдонуп жатат" "Бул колдонмо кайда жүргөнүңүздү ар дайым билип турат. Аны өзгөртүү үчүн таптап коюңуз." - "Колдонмону иштеп чыгуучулардын айтышы боюнча, дайындарыңыз төмөнкүдөй болушу мүмкүн:" - "Бул колдонмону иштеп чыгуучунун дайындарыңызды кандайча колдонгонун жактырбасаңыз, уруксаттардан баш тартсаңыз болот." - "Толук маалымат алуу үчүн %s колдонмосуна өтүңүз." - "Булутка жүктөлүп берилет" - "Уруксат берсеңиз, булутка жүктөлүп берилет" - "Жарнамачылар жана компаниялар менен бөлүшүлөт" - "Уруксат берсеңиз, жарнамачылар жана компаниялар менен бөлүшүлөт" - "Акча табуу үчүн колдонулат" - "Сиз уруксат бергенде, акча табууга колдонулат" - "Түбөлүккө сакталат жана талдалат" - "Сиз көрсөткөн узактыкка сакталган жана талдалган" - - %s аптага сакталып, талдалат - 1 аптага сакталып, талдалат - - "Колдонмону иштеп чыгуучу колдонмо дайындарыңызды кандайча колдонгонун көрсөткөн жок." "Колдонмо пайдаланылып жаткан учурда гана" "Колдонмого уруксаттар берилген жок" "Колдонмого бардык уруксаттар берилди" @@ -205,10 +184,18 @@ "Музыка колдонмосу" "Галерея колдонмосу" "Унаа режиминдеги \"Телефон\" колдонмосу" - "Проксиге чалуучу колдонмо" + + "Чалууларды башкаруу колдонмосу" "Чалууга коштомо колдонмо" - - + "Көмөкчү колдонмо" + "Унааны долбоорлоо колдонмосу" "Эскертүү: Эгер түзмөгүңүздү өчүрүп күйгүзгөндө экранды бөгөттөө жөндөлгөн болсо, түзмөктү бөгөттөн чыгармайынча бул колдонмо ачылбайт." + "Мүчүлүштүктөрдү оңдоо дайындарын бөлүшүү" + "Мүчүлүштүктөрдү оңдоо дайындары бөлүшүлсүнбү?" + "%1$s мүчүлүштүктөрдү оңдоо маалыматын жүктөп бергиси келет." + "Мүчүлүштүктөрдү оңдоо дайындарын бөлүшүү" + "%1$s бул түзмөктөн %2$s саат %3$s алынган мүчүлүштүк тууралуу кабарды жүктөп берүүнү суранды. Мүчүлүштүк тууралуу кабарларда түзмөгүңүз тууралуу маалымат, ошондой эле колдонуучу аттары, жайгашкан жер дайындары, түзмөктүн идентификаторлору жана тармак маалыматтары сыяктуу колдонмолор аркылуу киргизилген дайындар камтылат. Мүчүлүштүк тууралуу кабарларды өзүңүз ишенген адамдар жана колдонмолор менен гана бөлүшүңүз. %4$s колдонмосуна мүчүлүштүк тууралуу кабарды жүктөп берүүгө уруксат бересизби?" + "Уруксат берүү" + "Жок" diff --git a/res/values-lo/strings.xml b/res/values-lo/strings.xml index 5ddbebb68..3b4cfaee7 100644 --- a/res/values-lo/strings.xml +++ b/res/values-lo/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "ການນຳໃຊ້ສິດອະນຸຍາດສູງສຸດໃນ 24 ນາທີທີ່ຜ່ານມາ" "ການນຳໃຊ້ສິດອະນຸຍາດສູງສຸດໃນ 1 ນາທີທີ່ຜ່ານມາ" "ແອັບ" - - - - + "ກັ່ນຕອງແລ້ວໂດຍ: %1$s" + "ລຶບຕົວກັ່ນຕອງອອກ" "ກັ່ນຕອງຕາມ" "ກັ່ງຕອງຕາມສິດອະນຸຍາດ" "ສິດອະນຸຍາດຫຼາຍທີ່ສຸດ" "ການເຂົ້າເຖິງທີ່ຫຼາຍທີ່ສຸດ" "ຫຼ້າສຸດ" - - + "ໂຫຼດຄືນໃໝ່" "ການໃຊ້ສິດອະນຸຍາດແອັບ" "ເຂົ້າເຖິງ: %1$s ເທື່ອ. ໄລຍະເວລາທັງຮວມ: %2$s. ໃຊ້ຫຼ້າສຸດ %3$s ກ່ອນ." "ເຂົ້າເຖິງ: %1$s ເທື່ອ. ໃຊ້ຫຼ້າສຸດ %2$s ກ່ອນ." @@ -137,11 +134,9 @@ "%1$s ເຂົ້າເຖິງ %2$s ຂອງທ່ານເມື່ອ %3$sກ່ອນ." "%1$s ບໍ່ໄດ້ເຂົ້າເຖິງ %2$s ຂອງທ່ານ." "ເບິ່ງການໃຊ້ສິດອະນຸຍາດແບບລະອຽດ" - - + "ເຂົ້າເຖິງຫຼ້າສຸດ: %1$s" "ອະນຸຍາດແລ້ວ" - - + "ອະນຸຍາດສະເພາະໃນຕອນໃຊ້ຢູ່ເທົ່ານັ້ນ" "ຖືກປະຕິເສດ" "ເບິ່ງການນຳໃຊ້ແບບລະອຽດ" @@ -165,22 +160,6 @@ "ການແຈ້ງເຕືອນການອະນຸຍາດ" "%s ໄດ້ໃຊ້ສະຖານທີ່ຂອງທ່ານແລ້ວ" "ແອັບນີ້ສາມາດເຂົ້າເຖິງສະຖານທີ່ຂອງທ່ານໄດ້ຕະຫຼອດເວລາ. ແຕະເພື່ອປ່ຽນແປງ." - "ຜູ້ພັດທະນາແອັບບອກວ່າຂໍ້ມູນຂອງທ່ານອາດຈະ:" - "ຫາກທ່ານບໍ່ຮູ້ວ່າຜູ້ພັດທະນາແອັບນີ້ໃຊ້ຂໍ້ມູນຂອງທ່ານແນວໃດ, ທ່ານສາມາດປະຕິເສດສິດອະນຸຍາດໄດ້." - "ໄປທີ່ %s ເພື່ອເບິ່ງຂໍ້ມູນເພີ່ມເຕີມ." - "ອັບໂຫລດໄປໃສ່ຄລາວແລ້ວ" - "ອັບໂຫລດໄປໃສ່ຄລາວເມື່ອທ່ານອະນຸຍາດມັນຢ່າງຊັດເຈນ" - "ແບ່ງປັນກັບຜູ້ລົງໂຄສະນາ ຫຼື ທຸລະກິດຕ່າງໆ" - "ແບ່ງປັນກັບຜູ້ລົງໂຄສະນາ ຫຼື ທຸລະກິດຕ່າງໆເມື່ອທ່ານອະນຸຍາດຢ່າງຊັດເຈນ" - "ໃຊ້ສຳລັບການສ້າງລາຍໄດ້" - "ໃຊ້ສຳລັບການສ້າງລາຍໄດ້ເມື່ອທ່ານອະນຸຍາດຢ່າງຊັດເຈນ" - "ບັນທຶກ ແລະ ວິເຄາະຕະຫຼອດໄປ" - "ບັນທຶກ ແລະ ວິເຄາະເປັນໄລຍະເວລາທີ່ທ່ານລະບຸໄວ້" - - ບັນທຶກ ແລະ ວິເຄາະເປັນເວລາ %s ອາທິດ - ບັນທຶກ ແລະ ວິເຄາະເປັນເວລາ 1 ອາທິດ - - "ຜູ້ພັດທະນາແອັບບໍ່ໄດ້ລະບຸວິທີທີ່ແອັບໃຊ້ຂໍ້ມູນຂອງທ່ານ." "ສະເພາະເມື່ອມີການໃຊ້ແອັບ" "ບໍ່ມີສິດທີ່ອະນຸຍາດ" "ບໍ່ມີສິດອະນຸຍາດຖືກປະຕິເສດ" @@ -205,10 +184,18 @@ "ແອັບເພງ" "ແອັບຄັງ" "ແອັບໂທລະສັບໂໝດລົດ" - "ແອັບການໂທພຣັອກຊີ" + + "ແອັບກວດສອບການໂທ" "ແອັບແຖມການໂທ" - - + "ແອັບຜູ້ຊ່ວຍ" + "ແອັບ Car Projection" "ໝາຍເຫດ: ຫາກທ່ານຣີສະຕາດອຸປະກອນຂອງທ່ານ ແລະ ຕັ້ງການລັອກໜ້າຈໍໄວ້, ແອັບນີ້ຈະບໍ່ສາມາດໃຊ້ໄດ້ຈົນກວ່າທ່ານຈະປົດລັອກອຸປະກອນຂອງທ່ານ." + "ແບ່ງປັນຂໍ້ມູນການດີບັກ" + "ແບ່ງປັນຂໍ້ມູນການດີບັກແບບລະອຽດບໍ?" + "%1$s ຕ້ອງການອັບໂຫລດຂໍ້ມູນການດີບັກ." + "ແບ່ງປັນຂໍ້ມູນການດີບັກ" + "%1$s ກຳລັງຮ້ອງຂໍໃຫ້ອັບໂຫລດລາຍງານຂໍ້ຜິດພາດຈາກອຸປະກອນນີ້ຖືກບັນທຶກມາເມື່ອ %2$s ເວລາ %3$s. ລາຍງານຂໍ້ຜິດພາດຕ່າງໆຈະຮວມເອົາຂໍ້ມູນສ່ວນຕົວກ່ຽວກັບອຸປະກອນຂອງທ່ານ ຫຼື ຂໍ້ມູນທີ່ຈັດເກັບໄວ້ໂດຍແອັບ, ຕົວຢ່າງ ເຊັ່ນ: ຊື່ຜູ້ໃຊ້, ຂໍ້ມູນສະຖານທີ່, ຕົວລະບຸອຸປະກອນ ແລະ ຂໍ້ມູນເຄືອຂ່າຍ. ກະລຸນາແບ່ງປັນລາຍງານຂໍ້ຜິດພາດໃຫ້ສະເພາະຄົນ ແລະ ແອັບທີ່ທ່ານເຊື່ອຖືໃຫ້ເຂົ້າເຖິງຂໍ້ມູນນີ້ໄດ້ເທົ່ານັ້ນ. ອະນຸຍາດໃຫ້ %4$s ອັບໂຫລດລາຍງານຂໍ້ຜິດພາດບໍ?" + "ອະນຸຍາດ" + "ປະຕິເສດ" diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml index e20ea29c7..18c1711f7 100644 --- a/res/values-lt/strings.xml +++ b/res/values-lt/strings.xml @@ -4,9 +4,9 @@ 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. @@ -116,17 +116,14 @@ "Populiar. leidimų naudoj. per pastarąsias 15 min." "Populiar. leidimų naudojimas per pastarąją minutę" "Programos" - - - - + "Filtruota pagal: %1$s" + "Pašalinti filtrą" "Filtruoti pagal" "Filtruoti pagal leidimus" "Daugiausia leidimų" "Daugiausia kartų pasiekta" "Naujausi" - - + "Atnaujinti" "Programos leidimų naudojimas" "Prieiga: Kartų: %1$s. Visa trukmė: %2$s. Paskutinį kartą naudota prieš %3$s." "Prieiga: Kartų: %1$s. Paskutinį kartą naudota prieš %2$s." @@ -139,11 +136,9 @@ "Programa „%1$s“ prieš %3$s pasiekė: %2$s." "Programa „%1$s“ neturėjo prieigos prie: %2$s." "Žiūrėti išsamią leidimų naudojimo informaciją" - - + "Paskutinį kartą pasiekta: %1$s" "Leidžiama" - - + "Leidžiama, tik kol naudojama" "Atmesta" "Žr. išsamią naudojimo informaciją" @@ -175,24 +170,6 @@ "Leidimų priminimai" "Programa „%s“ naudojo jūsų vietovę" "Ši programa visada gali pasiekti jūsų vietovę. Palieskite, kad pakeistumėte." - "Programos kūrėjas sako, kad duomenys gali būti:" - "Jei jums nepatinka, kaip programos kūrėjas naudoja jūsų duomenis, galite atmesti leidimą." - "Daugiau informacijos rasite programoje „%s“." - "Įkeliama į debesį" - "Įkeliama į debesį, kai aiškiai tai leidžiate" - "Bendrinama su reklamuotojais arba įmonėmis" - "Bendrinama su reklamuotojais arba įmonėmis, kai aiškiai tai leidžiate" - "Naudojama siekiant gauti pajamų" - "Naudojama siekiant gauti pajamų, kai aiškiai tai leidžiate" - "Visada išsaugoma ir analizuojama" - "Saugoma ir analizuojama nurodytą laikotarpį" - - Saugoma ir analizuojama %s savaitę - Saugoma ir analizuojama %s savaites - Saugoma ir analizuojama %s savaitės - Saugoma ir analizuojama %s savaičių - - "Programos kūrėjas nenurodė, kaip programa naudoja jūsų duomenis." "Tik tada, kai programa naudojama" "Nesuteikta jokių leidimų" "Neatmesta jokių leidimų" @@ -217,10 +194,18 @@ "Muzikos programa" "Galerijos programa" "Automob. režimo tel. programa" - "Tarp. serverio iškv. programa" + + "Skambučių stebėjimo programa" "Papild. programos iškvietimas" - - + "Pagalbinė programa" + "Automob. projekcijos programa" "Pastaba. Jei esate nustatę ekrano užraktą ir iš naujo paleisite įrenginį, nebus galima atidaryti programos, kol neatrakinsite įrenginio." + "Derinimo duomenų bendrinimas" + "Bendrinti išsamius derinimo duomenis?" + "Programa „%1$s“ norėtų įkelti derinimo informaciją." + "Derinimo duomenų bendrinimas" + "Programa „%1$s“ prašo iš šio įrenginio įkelti pranešimą apie riktą, užfiksuotą %2$s, %3$s. Į pranešimus apie riktus įtraukiama asmens informacija apie įrenginį arba programų į žurnalą įrašyta informacija, pavyzdžiui, naudotojų vardai, vietovių duomenys, įrenginių identifikatoriai ir tinklo informacija. Pranešimus apie riktus bendrinkite tik su tais žmonėmis ir programomis, kuriais pasitikite ir kuriems galite patikėti šią informaciją. Leisti programai „%4$s“ įkelti pranešimą apie riktą?" + "Leisti" + "Atmesti" diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml index 3ec84fa17..24899fe4e 100644 --- a/res/values-lv/strings.xml +++ b/res/values-lv/strings.xml @@ -4,9 +4,9 @@ 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. @@ -115,17 +115,14 @@ "Biežāk izmantoto atļauju lietojums pēdējās 15 min" "Biežāk izmantoto atļauju lietojums pēdējā minūtē" "Lietotnes" - - - - + "Filtrēts pēc: %1$s" + "Noņemt filtru" "Filtrēt pēc" "Filtrēt pēc atļaujām" "Lielākā daļa atļauju" "Lielākais piekļuvju skaits" "Jaunākās" - - + "Atsvaidzināt" "Lietotņu atļauju lietojums" "Piekļuve: %1$s reizes. Kopējais ilgums: %2$s. Pēdējā lietošanas reize pirms šāda laika: %3$s." "Piekļuve: %1$s reizes. Pēdējā lietošanas reize pirms šāda laika: %2$s." @@ -138,11 +135,9 @@ "%1$s piekļuva jūsu atļaujai %2$s pirms: %3$s." "Lietotnei %1$s nav piekļuves %2$s." "Skatīt detalizētu informāciju par atļauju lietojumu" - - + "Pēdējā piekļuve: %1$s" "Atļauts" - - + "Atļauts tikai izmantošanas laikā" "Noraidīts" "Skatīt detalizētu lietojuma informāciju" @@ -170,23 +165,6 @@ "Atgādinājumi par atļauju" "Lietotne %s jau kādu laiku izmanto jūsu atrašanās vietu" "Šī lietotne jebkurā laikā var piekļūt jūsu atrašanās vietai. Pieskarieties, lai mainītu šo iestatījumu." - "Lietotnes izstrādātājs saka, ka jūsu dati, iespējams, ir:" - "Ja neesat apmierināts ar to, kā šis lietotnes izstrādātājs izmanto jūsu datus, varat noraidīt atļauju." - "Lai iegūtu plašāku informāciju, pārejiet uz lietotni %s." - "Augšupielādēts mākonī" - "Augšupielādēts mākonī, ja jūs to skaidri atļaujat" - "Kopīgots ar reklāmdevējiem vai uzņēmumiem" - "Kopīgots ar reklāmdevējiem vai uzņēmumiem, ja jūs to skaidri atļaujat" - "Izmantots monetizācijai" - "Izmantots monetizācijai, ja jūs to skaidri atļaujat" - "Saglabāts un analizēts bezgalīgi" - "Saglabāts un analizēts tik ilgi, cik esat norādījis" - - Saglabāts un analizēts %s nedēļas - Saglabāts un analizēts %s nedēļu - Saglabāts un analizēts %s nedēļas - - "Lietotnes izstrādātājs nenorādīja, kā lietotne izmantos jūsu datus." "Tikai lietotnes izmantošanas laikā" "Nav piešķirta neviena atļauja" "Nav noraidīta neviena atļauja" @@ -211,10 +189,18 @@ "Mūzikas lietotne" "Galerijas lietotne" "Auto režīma tālruņu lietotne" - "Starpniekservera zvanu lietotne" + + "Zvanu pārvaldības lietotne" "Zvanu palīglietotne" - - + "Palīga lietotne" + "Projicēš. automašīnā lietotne" "Piezīme. Ja esat iestatījis ekrāna bloķēšanu un restartēsiet ierīci, šo lietotni varēs startēt tikai pēc ierīces atbloķēšanas." + "Atkļūdošanas datu kopīgošana" + "Vai kopīgot detalizētus atkļūdošanas datus?" + "%1$s vēlas augšupielādēt atkļūdošanas informāciju." + "Atkļūdošanas datu kopīgošana" + "%1$s pieprasa augšupielādēt kļūdas pārskatu no šīs ierīces, kas veikts: %2$s plkst. %3$s. Kļūdu pārskatos ir ietverta personas informācija par jūsu ierīci vai lietotnēs reģistrēta informācija, piemēram, lietotājvārdi, atrašanās vietas dati, ierīču identifikatori un tīkla informācija. Kopīgojiet kļūdu pārskatus tikai ar lietotājiem un lietotnēm, kuriem uzticat šo informāciju. Vai atļaut lietotnei %4$s augšupielādēt kļūdas pārskatu?" + "Atļaut" + "Neatļaut" diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml index dd042a06b..1207612c7 100644 --- a/res/values-mk/strings.xml +++ b/res/values-mk/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "Користење најчести дозволи во последните 15 минути" "Користење најчести дозволи во последната 1 минута" "Апликации" - - - - + "Филтрирано според: %1$s" + "Отстрани го филтерот" "Филтрирајте според" "Филтрирај според дозволите" "Најмногу дозволи" "Најмногу пристапи" "Неодамнешни" - - + "Освежи" "Дозволи за апликација" "Пристап: %1$s пати. Вкупно времетраење: %2$s. Последно користење пред %3$s." "Пристап: %1$s пати. Последно користење пред %2$s." @@ -137,11 +134,9 @@ "%1$s пристапи до %2$s пред %3$s." "%1$s не пристапила до вашата %2$s." "Прегледајте го деталното користење на дозволите" - - + "Последен пристап: %1$s" "Дозволени" - - + "Дозволени само кога се користат" "Одбиени" "Прикажи го деталното користење" @@ -165,22 +160,6 @@ "Потсетници за дозволата" "%s ја користи вашата локација" "Апликацијава секогаш може да пристапува до вашата локација. Допрете за да го промените тоа." - "Програмерот на апликацијата вели дека вашите податоци може да:" - "Ако не ви се допаѓа како програмеров на аликацијата ги користи вашите податоци, може да ја одбиете дозволата." - "Одете на %s за повеќе информации." - "се прикачуваат во облак" - "се прикачуваат во облак кога експлицитно ќе го дозволите тоа" - "се споделуваат со огласувачи и бизниси" - "се споделуваат со огласувачи и бизниси кога експлицитно ќе го дозволите тоа" - "се користат за монетаризација" - "се користат за монетаризација кога експлицитно ќе го дозволите тоа" - "се зачувуваат и анализираат засекогаш" - "се зачувуваат и анализираат во времето што ќе го определите" - - се зачувуваат и анализираат %s седмица - се зачувуваат и анализираат %s седмици - - "Програмерот на апликацијата не назначил како апликацијата ги користи вашите податоци." "Само додека се користи апликацијата" "Нема овозможени дозволи" "Нема одбиени дозволи" @@ -205,10 +184,18 @@ "Апликација за музика" "Апликација за галерија" "Телефонска апликација Car mode" - "Аплик. за повикување прокси" + + "Аплик. за проверка на повици" "Повикај придружна апликација" - - + "Апликација за помош" + "Апликација Car Projection" "Забелешка: Ако го рестартирате уредот, а имате поставено заклучување на екранот, апликацијава нема да може да се стартува додека не го отклучите уредот." + "Споделете податоци за отстранување грешки" + "Да се споделат податоци за отстранување грешки?" + "%1$s сака да прикачи информации за отстранување грешки." + "Споделете податоци за отстранување грешки" + "%1$s бара да прикачи извештај за грешка од уредов снимен на %2$s во %3$s. Извештаите за грешки вклучуваат лични информации за вашиот уред или пак информации евидентирани од апликациите, на пр., кориснички имиња, податоци за локацијата, идентификатори на уредот и информации за мрежата. Споделувајте извештаи за грешки само со луѓе и апликации во кои имате доверба кога станува збор за овие информации. Да ѝ се дозволи на %4$s да прикачи извештај за грешка?" + "Дозволи" + "Одбиј" diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml index 8ad74493b..481d82a66 100644 --- a/res/values-ml/strings.xml +++ b/res/values-ml/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "പൊതുവായ അനുമതിയുടെ കഴിഞ്ഞ 15 മിനിറ്റിലെ ഉപയോഗം" "പൊതുവായ അനുമതിയുടെ കഴിഞ്ഞ ഒരു മിനിറ്റിലെ ഉപയോഗം" "ആപ്പുകൾ" - - - - + "ഇതുപ്രകാരം ഫിൽട്ടർ ചെയ്‌‌തു: %1$s" + "ഫിൽട്ടർ നീക്കം ചെയ്യുക" "ഇതുപ്രകാരം ഫിൽട്ടർ ചെയ്യുക" "അനുമതികൾ പ്രകാരം ഫിൽട്ടർ ചെയ്യുക" "ഏറ്റവുമധികം ഉപയോഗിച്ച അനുമതികൾ" "ഏറ്റവുമധികം ആക്‌സസ് ചെയ്‌തത്" "ഏറ്റവും പുതിയവ" - - + "പുതുക്കിയെടുക്കുക" "ആപ്പ് അനുമതികളുടെ ഉപയോഗം" "ആക്‌സസ്: %1$s തവണ. ആകെ ദൈർഘ്യം: %2$s. അവസാനം ഉപയോഗിച്ചത് %3$s മുമ്പ്." "ആക്‌സസ്: %1$s തവണ. അവസാനം ഉപയോഗിച്ചത് %2$s മുമ്പ്." @@ -137,11 +134,9 @@ "%1$s നിങ്ങളുടെ %2$s, %3$s മുമ്പ് ആക്‌സസ് ചെയ്‌തു." "%1$s നിങ്ങളുടെ %2$sആക്‌‌സസ് ചെയ്‌തിട്ടില്ല." "അനുമതികളുടെ വിശദമായ ഉപയോഗം കാണുക" - - + "അവസാനം ആക്‌‌സസ് ചെയ്‌തത്: %1$s" "അനുവദിച്ചവ" - - + "ഉപയോഗിക്കുമ്പോൾ മാത്രം അനുവദനീയം" "നിരസിച്ചവ" "വിശദമായ ഉപയോഗം കാണുക" @@ -165,22 +160,6 @@ "അനുമതിയ്ക്കുള്ള റിമൈൻഡറുകൾ" "%sഎന്ന ആപ്പ് നിങ്ങളുടെ ലൊക്കേഷൻ ഉപയോഗിക്കുന്നു" "ഈ ആപ്പിന് എപ്പോഴും നിങ്ങളുടെ ലൊക്കേഷൻ ആക്‌സസ് ചെയ്യാനാവും. മാറ്റാൻ ടാപ്പ് ചെയ്യുക." - "നിങ്ങളുടെ ഡാറ്റ ഇനിപ്പറയുന്ന രീതിയിൽ ഉപയോഗിച്ചേക്കാം എന്ന് ആപ്പ് ഡെവലപ്പർ പറയുന്നു:" - "ഈ ആപ്പ് ഡെവലപ്പർ നിങ്ങളുടെ ഡാറ്റ ഉപയോഗിക്കുന്ന രീതി ഇഷ്‌ടമല്ലെങ്കിൽ, അനുമതി നിരസിക്കാം." - "കൂടുതൽ വിവരങ്ങൾക്ക്, %s-ലേക്ക് പോവുക" - "ക്ലൗഡിലേക്ക് അപ്‌ലോഡ് ചെയ്‌തേക്കാം" - "നിങ്ങൾ സ്‌പഷ്‌ടമായി അനുവദിക്കുമ്പോൾ ക്ലൗഡിലേക്ക് അപ്‌ലോഡ് ചെയ്‌തേക്കാം" - "പരസ്യദാതാക്കളുമായോ ബിസിനസുകളുമായോ പങ്കിട്ടേക്കാം" - "നിങ്ങൾ സ്‌പഷ്‌ടമായി അനുവദിക്കുമ്പോൾ പരസ്യദാതാക്കളുമായോ ബിസിനസുകളുമായോ പങ്കിട്ടേക്കാം" - "ധനം സമ്പാദിക്കാൻ ഉപയോഗിച്ചേക്കാം" - "നിങ്ങൾ സ്‌പഷ്‌ടമായി അനുവദിക്കുമ്പോൾ ധനം സമ്പാദിക്കാൻ ഉപയോഗിച്ചേക്കാം" - "ശാശ്വതമായി സംരക്ഷിച്ച് വിശകലനം ചെയ്‌തേക്കാം" - "നിങ്ങൾ വ്യക്തമാക്കുന്ന കാലയളവിൽ സംരക്ഷിച്ച് വിശകലനം ചെയ്‌തേക്കാം" - - %s ആഴ്‌ചത്തേയ്ക്ക് സംരക്ഷിച്ച് വിശകലനം ചെയ്‌തേക്കാം - ഒരാഴ്‌ചത്തേയ്ക്ക് സംരക്ഷിച്ച് വിശകലനം ചെയ്‌തേക്കാം - - "ആപ്പ് നിങ്ങളുടെ ഡാറ്റ ഉപയോഗിക്കുന്ന രീതി, ആപ്പ് ഡെവലപ്പർ വ്യക്തമാക്കിയിട്ടില്ല." "ആപ്പ് ഉപയോഗത്തിലുള്ളപ്പോൾ മാത്രം" "അനുമതികളൊന്നും നൽകിയിട്ടില്ല" "അനുമതികളൊന്നും നിഷേധിച്ചിട്ടില്ല" @@ -205,10 +184,18 @@ "സംഗീത ആപ്പ്" "ഗാലറി ആപ്പ്" "കാർ മോഡ് ഫോൺ ആപ്പ്" - "പ്രോക്‌സി കോൾ ചെയ്യുന്ന ആപ്പ്" + + "കോൾ സ്‌ക്രീനിംഗ് ആപ്പ്" "കോൾ സഹകാരി ആപ്പ്" - - + "സഹായ ആപ്പ്" + "കാർ പ്രൊജക്ഷൻ ആപ്പ്" "ശ്രദ്ധിക്കുക: നിങ്ങളുടെ ഉപകരണം റീസ്‌റ്റാർട്ട് ചെയ്‌ത്, സ്‌ക്രീൻ ലോക്ക് സജ്ജീകരിച്ചിട്ടുണ്ടെങ്കിൽ, നിങ്ങളുടെ ഉപകരണം അൺലോക്ക് ചെയ്യുന്നത് വരെ ഈ ആപ്പ് ആരംഭിക്കാനാവില്ല." + "ഡീബഗ്ഗ് ചെയ്യൽ ഡാറ്റ പങ്കിടുക" + "വിശദമായ ഡീബഗ്ഗ് ചെയ്യൽ വിവരങ്ങൾ പങ്കിടണോ?" + "ഡീബഗ്ഗ് ചെയ്യൽ വിവരങ്ങൾ അപ്‌ലോഡ് ചെയ്യാൻ %1$s താൽപ്പര്യപ്പെടുന്നു." + "ഡീബഗ്ഗ് ചെയ്യൽ ഡാറ്റ പങ്കിടുക" + "ഈ ഉപകരണത്തിൽ നിന്ന് %2$s-ന് %3$s-മണിയ്ക്ക് എടുത്ത ഒരു ബഗ് റിപ്പോർട്ട് അപ്‌ലോഡ് ചെയ്യാൻ %1$s അഭ്യർത്ഥിക്കുന്നു. നിങ്ങളുടെ ഉപകരണത്തെക്കുറിച്ചുള്ള വ്യക്തിഗത വിവരമോ ആപ്പുകൾ ലോഗ് ചെയ്യുമ്പോൾ നൽകുന്ന വിവരമോ, ഉദാഹരണത്തിന് നെറ്റ്‌വർക്ക് വിവരങ്ങൾ, ഉപകരണ ഐഡന്റിഫയറുകൾ, ലൊക്കേഷൻ ഡാറ്റ, ഉപയോക്തൃനാമങ്ങൾ എന്നിവ ബഗ് റിപ്പോർട്ടുകളിൽ ഉൾപ്പെടുന്നു. ഈ വിവരം ഉപയോഗിച്ച് നിങ്ങൾ വിശ്വസിക്കുന്ന ആപ്പുകൾക്കും ആളുകൾക്കും മാത്രം ബഗ് റിപ്പോർട്ടുകൾ പങ്കിടുക. %4$s എന്നതിനെ ഒരു ബഗ് റിപ്പോർട്ട് അപ്‌ലോഡ് ചെയ്യാൻ അനുവദിക്കണോ?" + "അനുവദിക്കുക" + "നിരസിക്കുക" diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml index 48ef3db2e..1035c1242 100644 --- a/res/values-mn/strings.xml +++ b/res/values-mn/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "Сүүлийн 15 минутад хамгийн их ашиглагдсан зөвшөөрөл" "Сүүлийн 1 минутад хамгийн их ашиглагдсан зөвшөөрөл" "Аппууд" - - - - + "Шүүсэн: %1$s" + "Шүүлтийг устгах" "Дараахаар шүүх" "Зөвшөөрлөөр шүүх" "Хамгийн олон зөвшөөрөл" "Хамгийн олон хандалт" "Саяхны" - - + "Сэргээх" "Аппын зөвшөөрлийн ашиглалт" "Хандалт: %1$s удаа. Нийт хугацаа: %2$s. Хамгийн сүүлд %3$s-н өмнө ашигласан." "Хандалт: %1$s удаа. Хамгийн сүүлд %2$s-н өмнө ашигласан." @@ -137,11 +134,9 @@ "%1$s таны %2$s%3$s-н өмнө хандсан байна." "%1$s таны %2$s-д хандаагүй байна." "Зөвшөөрлийн дэлгэрэнгүй ашиглалтыг харах" - - + "Хамгийн сүүлийн хандалт: %1$s" "Зөвшөөрсөн" - - + "Зөвхөн ашиглалтад байхад зөвшөөрөгдсөн" "Татгалзсан" "Дэлгэрэнгүй ашиглалтыг харах" @@ -165,22 +160,6 @@ "Зөвшөөрлийн сануулагч" "%s таны байршлыг ашигласаар байна" "Энэ апп таны байршилд тогтмол хандах боломжтой байна. Өөрчлөхийн тулд товшино уу." - "Апп хөгжүүлэгч таны өгөгдлийг дараах байдлаар ашиглаж болзошгүй:" - "Танд энэ апп хөгжүүлэгчийн таны өгөгдлийг хэрхэн ашиглаж байгаа нь таалагдахгүй байвал зөвшөөрлөөс татгалзаж болно." - "Нэмэлт мэдээлэл авахын тулд %s-д очно уу." - "Үүлэнд байршуулна" - "Таныг тодорхой байдлааар зөвшөөрсөн тохиолдолд үүлэнд байршуулна" - "Сурталчлагчид эсвэл бизнесүүдтэй хуваалцана" - "Таныг тодорхой байдлаар зөвшөөрсөн тохиолдолд сурталчлагчид эсвэл бизнесүүдтэй хуваалцана" - "Мөнгө олох арга болгож ашиглана" - "Таныг тодорхой байдлаар зөвшөөрсөн тохиолдолд үүнийг мөнгө олох арга болгож ашиглана" - "Бүрмөсөн хадгалж, анализ хийнэ" - "Таны тогтоосон хугацааны турш хадгалж, анализ хийнэ" - - %s долоо хоногийн турш хадгалж, анализ хийнэ - 1 долоо хоногийн турш хадгалж, анализ хийнэ - - "Апп хөгжүүлэгч энэ апп таны өгөгдлийг хэрхэн ашиглах талаар тодорхойлоогүй байна." "Зөвхөн аппыг ашиглаж байх үед" "Ямар ч зөвшөөрөл алга" "Татгалзсан зөвшөөрөл алга" @@ -205,10 +184,18 @@ "Хөгжмийн апп" "Галерейны апп" "Машины горимын утасны апп" - "Прокси дуудлагын апп" + + "Дуудлага шүүх апп" "Дуудлага дэмжигч апп" - - + "Туслах пп" + "Машины үнэлгээний апп" "Санамж: Хэрвээ та төхөөрөмжөө дахин эхлүүлж, дэлгэцийн түгжээ тохируулбал энэ апп таныг төхөөрөмжийнхөө түгжээг тайлах хүртэл эхлэх боломжгүй." + "Алдаа засах өгөгдлийг хуваалцах" + "Алдаа засах дэлгэрэнгүй өгөгдлийг хуваалцах уу?" + "%1$s алдаа засах мэдээллийг байршуулах хүсэлтэй байна." + "Алдаа засах өгөгдлийг хуваалцах" + "%1$s энэ төхөөрөмжөөс %2$s%3$s-д авсан алдааны мэдээг байршуулах хүсэлт тавьж байна. Алдааны мэдээнд таны төхөөрөмжийн талаарх эсвэл хэрэглэгчийн нэр, байршлын өгөгдөл, төхөөрөмжийн таниулбар болон сүлжээний мэдээлэл зэрэг аппуудын бүртгэсэн хувийн мэдээллийг агуулна. Та алдааны мэдээг зөвхөн энэ мэдээллийг хуваалцахдаа итгэлтэй байгаа хүмүүс болон аппуудтай хуваалцана уу. %4$s-д алдааны мэдээг байршуулахыг зөвшөөрөх үү?" + "Зөвшөөрөх" + "Татгалзах" diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml index 61d4b42ba..e829fbcec 100644 --- a/res/values-mr/strings.xml +++ b/res/values-mr/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "मागील १५ मिनिटांतील टॉप परवानगी वापर" "मागील एक मिनिटामधील टॉप परवानगी वापर" "अॅप्स" - - - - + "यानुसार फिल्टर केले: %1$s" + "फिल्टर काढून टाका" "यानुसार फिल्टर करा" "परवानग्यांनुसार फिल्टर करा" "सर्वाधिक परवानग्या" "सर्वाधिक अॅक्सेस" "नुकतेच" - - + "रिफ्रेश करा" "अ‍ॅप परवानग्यांचा वापर" "अॅक्सेस करा: %1$s वेळा. एकूण कालावधी: %2$s. %3$s पूर्वी शेवटचे वापरले." "अॅक्सेस करा: %1$s वेळा. %2$s पूर्वी शेवटचे वापरले." @@ -137,11 +134,9 @@ "%1$s ने तुमची %2$s %3$s पूर्वी अॅक्सेस केली." "%1$s ला तुमच्या %2$sचा अॅक्सेस दिलेला नाही." "परवानग्यांचा वापर तपशीलवार पाहा" - - + "शेवटचा अ‍ॅक्सेस: %1$s" "अनुमती असलेले" - - + "फक्त वापरत असताना अनुमती आहे" "नाकारलेली" "तपशीलवार वापर पाहा" @@ -165,22 +160,6 @@ "परवानगी रिमाइंडर" "%s तुमचे स्थान वापरत आहे" "हे अ‍ॅप नेहमी तुमचे स्थान अॅक्सेस करू शकते. बदलण्यासाठी टॅप करा." - "ॲप डेव्हलपरच्या म्हणण्यानुसार तुमचा डेटा कदाचित:" - "ॲप डेव्हलपर तुमचा डेटा ज्याप्रमाणे वापरतो ते जर तुम्हाला आवडत नसेल तर तुम्ही परवानगी नाकारू शकता." - "अधिक माहितीसाठी %s वर जा." - "क्लाउडवर अपलोड केलेले" - "जेव्हा तुम्ही स्पष्टपणे परवानगी देता तेव्हा क्लाउडवर अपलोड केलेले" - "जाहिरातदार किंवा व्यवसायासोबत शेअर केलेले" - "तुम्ही स्पष्टपणे परवानगी देता तेव्हा जाहिरातदार किंवा व्यवसायासोबत शेअर केलेले" - "कमाईसाठी वापरलेला" - "तुम्ही स्पष्टपणे अनुमती देता तेव्हा कमाईसाठी वापरली जाते" - "सेव्ह आणि कायमस्वरूपी विश्लेषण केलेले" - "तुम्ही नमूद केलेल्या कालावधीसाठी सेव्ह आणि विश्लेषण केलेले" - - %sआठवड्यासाठी सेव्ह आणि विश्लेषण केलेले - %sआठवड्यांसाठी सेव्ह आणि विश्लेषण केलेले - - "ॲप किती डेटा वापरेल हे ॲप डेव्हलपरने नमूद केलेले नाही." "फक्त अ‍ॅप वापरत असताना" "कोणत्याही परवानगीची अनुमती नाही" "कोणत्याही परवानग्या नाकारल्या नाहीत" @@ -205,10 +184,18 @@ "म्युझिक अ‍ॅप" "गॅलरी अ‍ॅप" "कार मोड फोन अ‍ॅप" - "प्रॉक्सी कॉलिंग अ‍ॅप" + + "स्क्रीनिंग अ‍ॅपला कॉल करा" "सहयोगी अ‍ॅपला कॉल करा" - - + "साहाय्य अ‍ॅप" + "कार प्रोजेक्शन अ‍ॅप" "टीप: तुम्ही तुमचे डिव्हाइस रीस्टार्ट केल्यास आणि स्क्रीन लॉक सेट केले असल्यास, तुम्ही तुमचे डिव्हाइस अनलॉक करेपर्यंत हे अ‍ॅप सुरू होऊ शकत नाही." + "डीबगिंग डेटा शेअर करा" + "तपशीलवार डीबगिंग डेटा शेअर करायचा?" + "%1$s ला डीबगिंग माहिती अपलोड करायला आवडेल." + "डीबगिंग डेटा शेअर करा" + "%1$s %2$s रोजी %3$s वाजता घेतलेल्या या डिव्हाइसमधून बग रिपोर्ट अपलोड करण्याची विनंती करत आहे. बग रिपोर्टमध्ये तुमच्या डिव्हाइसविषयीच्या किंवा अ‍ॅप्सने लॉग केलेल्या वैयक्तिक माहितीचा समावेश अहे, उदाहरणार्थ वापरकर्ता नावे, स्थान डेटा, डिव्हाइस आयडेंटिफायर आणि नेटवर्क माहिती. या माहितीसह फक्त तुम्हाला विश्वास असलेल्या लोकांसह आणि अ‍ॅप्ससह बग रिपोर्ट शेअर करा. %4$s ला बग रिपोर्ट अपलोड करण्याची अनुमती द्यायची?" + "अनुमती द्या" + "नकार द्या" diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml index 34ab3c354..9fde4f99e 100644 --- a/res/values-ms/strings.xml +++ b/res/values-ms/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "Penggunaan kebenaran terbanyak dlm 15 min terakhir" "Penggunaan kebenaran terbanyak dlm 1 min terakhir" "Apl" - - - - + "Ditapis mengikut: %1$s" + "Alih keluar penapis" "Tapis mengikut" "Tapis mengikut kebenaran" "Paling banyak kebenaran" "Paling banyak akses" "Terbaharu" - - + "Muat smula" "Penggunaan kebenaran apl" "Akses: %1$s kali. Jumlah tempoh: %2$s. Terakhir digunakan %3$s yang lalu." "Akses: %1$s kali. Terakhir digunakan %2$s yang lalu." @@ -137,11 +134,9 @@ "%1$s mengakses %2$s anda %3$s yang lalu." "%1$s belum mengakses %2$s anda." "Lihat penggunaan kebenaran terperinci" - - + "Akses terakhir: %1$s" "Dibenarkan" - - + "Dibenarkan hanya semasa dalam penggunaan" "Ditolak" "Lihat penggunaan terperinci" @@ -165,22 +160,6 @@ "Peringatan kebenaran" "%s telah menggunakan lokasi anda" "Apl ini boleh mengakses lokasi anda pada setiap masa. Ketik untuk menukar." - "Pembangun apl mengatakan bahawa data anda mungkin:" - "Jika anda tidak menyukai cara pembangun apl ini menggunakan data anda, anda boleh menolak kebenaran itu." - "Pergi ke %s untuk mendapatkan maklumat lanjut." - "Dimuat naik ke awan" - "Dimuat naik ke awan apabila anda membenarkannya secara jelas" - "Dikongsi dengan pengiklan atau perniagaan" - "Dikongsi dengan pengiklan atau perniagaan apabila anda membenarkannya secara jelas" - "Digunakan untuk pengewangan" - "Digunakan untuk pengewangan apabila anda membenarkannya secara jelas." - "Disimpan dan dianalisis selama-lamanya" - "Diimpan dan dianalisis untuk tempoh yang anda tetapkan" - - Disimpan dan dianalisis selama %s minggu - Disimpan dan dianalisis selama 1 minggu - - "Pembangun tidak menetapkan cara apl menggunakan data anda." "Hanya semasa apl sedang digunakan" "Tiada kebenaran dibenarkan" "Tiada kebenaran ditolak" @@ -205,10 +184,18 @@ "Apl Muzik" "Apl Galeri" "Apl telefon mod kereta" - "Apl panggilan proksi" + + "Apl penyaringan panggilan" "Apl rakan panggilan" - - + "Apl Bantu" + "Apl Unjuran Kereta" "Nota: Jika anda memulakan semula peranti dan telah menetapkan kunci skrin, apl ini tidak boleh dimulakan sehingga anda membuka kunci peranti anda." + "Kongsi Data Penyahpepijatan" + "Kongsi data penyahpepijatan secara terperinci?" + "%1$s mahu memuat naik maklumat penyahpepijatan." + "Kongsi Data Penyahpepijatan" + "%1$s mahu memuat naik laporan pepijat daripada peranti ini yang diambil pada %2$s pada %3$s. Laporan pepijat termasuk maklumat peribadi tentang peranti anda atau yang dilog oleh apl, contohnya, nama pengguna, data lokasi, pengecam peranti dan maklumat rangkaian. Kongsi laporan pepijat dengan orang dan apl yang anda percayai sahaja berhubung maklumat ini. Benarkan %4$s memuat naik laporan pepijat?" + "Benarkan" + "Tolak" diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml index 80f1293c4..b91b08cd1 100644 --- a/res/values-my/strings.xml +++ b/res/values-my/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "ပြီးခဲ့သော ၁၅ မိနစ်ရှိ ထိပ်တန်းခွင့်ပြု သုံးစွဲမှု" "ပြီးခဲ့သော ၁ မိနစ်က ထိပ်တန်းခွင့်ပြုချက်သုံးစွဲမှု" "အက်ပ်များ" - - - - + "စစ်ထုတ်စနစ်- %1$s" + "စစ်ထုတ်ခြင်းကို ဖယ်ရှားရန်" "အောက်ပါဖြင့် စစ်ထုတ်ရန်-" "ခွင့်ပြုချက်များဖြင့် စစ်ထုတ်ရန်" "အများဆုံး ခွင့်ပြုချက်များ" "အများဆုံး အသုံးပြုမှု" "လတ်တလော" - - + "ပြန်စရန်" "အက်ပ်ခွင့်ပြုချက် အသုံးပြုမှု" "အသုံးပြုမှု− %1$s ကြိမ်။ စုစုပေါင်း ကြာချိန်− %2$s။ ပြီးခဲ့သည့် %3$s က အသုံးပြုထားသည်။" "အသုံးပြုမှု− %1$s ကြိမ်။ ပြီးခဲ့သည့် %2$s က အသုံးပြုခဲ့သည်။" @@ -137,11 +134,9 @@ "%1$s က သင်၏ %2$s ကို ပြီးခဲ့သော %3$s က ဝင်သုံးထားသည်။" "%1$s က သင်၏ %2$s ကို ဝင်သုံးမထားပါ။" "ခွင့်ပြုချက်များ အသုံးပြုမှု အသေးစိတ်ကို ကြည့်ရန်" - - + "နောက်ဆုံး အသုံးပြုချိန်- %1$s" "ခွင့်ပြုထားသည်" - - + "အသုံးပြုစဉ်တွင်သာ ခွင့်ပြုထားသည်" "ငြင်းပယ်ထားသည်" "အသေးစိတ်အသုံးပြုမှုကို ကြည့်ရန်" @@ -165,22 +160,6 @@ "ခွင့်ပြုချက် သတိပေးမှုများ" "%s က သင်၏တည်နေရာကို အသုံးပြုနေပါသည်" "ဤအက်ပ်က သင်၏တည်နေရာကို အမြဲဝင်ကြည့်နိုင်ပါသည်။ ပြောင်းရန် တို့ပါ။" - "အက်ပ်ဆော့ဖ်ဝဲအင်ဂျင်နီယာက သင့်ဒေတာများသည် အောက်ပါတို့ဖြစ်နိုင်သည်ဟု ဆိုပါသည်-" - "ဤအက်ပ်ဆော့ဖ်ဝဲအင်ဂျင်နီယာက သင့်ဒေတာများအား အသုံးပြုပုံကို မနှစ်သက်လျှင် ခွင့်ပြုချက်ကို သင်ငြင်းပယ်နိုင်သည်။" - "နောက်ထပ် အချက်အလက်များအတွက် %s သို့ သသွားပါ။" - "cloud သို့ အပ်လုဒ်လုပ်ထားသည်" - "သင်က ၎င်းကို တိကျပြတ်သားစွာ ခွင့်ပြုလျှင် cloud သို့ အပ်လုဒ်လုပ်ပါသည်" - "ကြော်ငြာရှင်များ သို့မဟုတ် လုပ်ငန်းများနှင့် မျှဝေထားသည်" - "သင်က ၎င်းကို တိကျပြတ်သားစွာ ခွင့်ပြုလျှင် ကြော်ငြာရှင်များ သို့မဟုတ် လုပ်ငန်းများနှင့် မျှဝေပါသည်" - "ဝင်ငွေရှာခြင်းအတွက် သုံးထားသည်" - "သင်က ၎င်းကို တိကျပြတ်သားစွာ ခွင့်ပြုလျှင် ဝင်ငွေရှာခြင်းအတွက် အသုံးပြုပါသည်" - "အမြဲတမ်းအတွက် သိမ်းပြီး ပိုင်းခြားစစ်ဆေးထားသည်" - "သင်သတ်မှတ်ထားသည့် ကာလအတွက် သိမ်းပြီး ပိုင်းခြားစစ်ဆေးထားသည်" - - %s ပတ်ကြာ သိမ်းပြီး ပိုင်းခြားစစ်ဆေးထားသည် - ၁ ပတ်ကြာ သိမ်းပြီး ပိုင်းခြားစစ်ဆေးထားသည် - - "အက်ပ်က သင့်ဒေတာကို မည်သို့အသုံးပြုမည်အား အက်ပ်ဆော့ဖ်ဝဲအင်ဂျင်နီယာက ဖော်ပြမထားပါ။" "အက်ပ်ကို အသုံးပြုနေစဉ်သာ" "ခွင့်ပြုချက်များ ပေးမထားပါ" "ခွင့်ပြုချက်များကို ငြင်းပယ်မထားပါ" @@ -205,10 +184,18 @@ "တေးဂီတ အက်ပ်" "ပုံပြခန်းအက်ပ်" "ကားမုဒ်ဖုန်းအက်ပ်" - "ပရောက်စီခေါ်ဆိုခြင်းအက်ပ်" + + "ခေါ်ဆိုမှု စစ်ဆေးခြင်းအက်ပ်" "ခေါ်ဆိုမှု အကူအညီအက်ပ်" - - + "အကူအညီ အက်ပ်" + "ကားပုံစံပြသည့် အက်ပ်" "မှတ်ချက်- သင်၏စက်ပစ္စည်းကို ပြန်လည်စတင်ပြီး မျက်နှာပြင်လော့ခ်ချထားလျှင် ၎င်းကို လော့ခ်မဖွင့်မချင်း ဤအက်ပ်ကို အသုံးပြု၍မရပါ။" + "အမှားရှာပြင်သည့် ဒေတာ မျှဝေခြင်း" + "အမှားရှာပြင်သည့် ဒေတာ အသေးစိတ်ကို မျှဝေလိုသလား။" + "%1$s က အမှားရှာပြင်သည့် အချက်အလက်ကို အပ်လုဒ်လုပ်လိုသည်။" + "အမှားရှာပြင်သည့် ဒေတာ မျှဝေခြင်း" + "%1$s သည် ဤကိရိယာက %2$s %3$s တွင် ရယူထားသည့် ချွတ်ယွင်းမှု အစီရင်ခံစာကို အပ်လုဒ်လုပ်ရန် တောင်းဆိုနေသည်။ ချွတ်ယွင်းမှု အစီရင်ခံစာတွင် သင့်ကိရိယာ သို့မဟုတ် အက်ပ်များဖြင့် အကောင့်ဝင်ရောက်ထားသည့် အသုံးပြုသူအမည်၊ တည်နေရာဒေတာ၊ ကိရိယာ သတ်မှတ်မှုစနစ်များနှင့် ကွန်ရက်အချက်အလက်တို့ကဲ့သို့ ကိုယ်ရေးကိုယ်တာအချက်လက်များ ပါဝင်သည်။ ဤအချက်အလက်နှင့် ပတ်သက်ပြီး သင်ယုံကြည်ရသည့် လူ၊ အက်ပ်များနှင့်သာ ချွတ်ယွင်းမှု အစီရင်ခံစာကို မျှဝေပါ။ %4$s ကို ချွတ်ယွင်းမှု အစီရင်ခံစာ အပ်လုဒ်လုပ်ခွင့်ပေးမလား။" + "ခွင့်ပြုရန်" + "ငြင်းပယ်ရန်" diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml index 48865ee70..a0f2982c6 100644 --- a/res/values-nb/strings.xml +++ b/res/values-nb/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "Hyppigste bruk av tillatelse de siste 15 minuttene" "Hyppigste bruk av tillatelser det siste minuttet" "Apper" - - - - + "Filtrert etter: %1$s" + "Fjern filteret" "Filtrér etter" "Filtrér etter tillatelser" "Flest tillatelser" "Mest brukt" "Nylig" - - + "Last inn på nytt" "Bruk av apptillatelser" "Tilgang: %1$s ganger. Total varighet: %2$s. Sist brukt for %3$s siden." "Tilgang: %1$s ganger. Sist brukt for %2$s siden." @@ -137,11 +134,9 @@ "%1$s har brukt %2$s for %3$s siden." "%1$s har ikke brukt %2$s." "Vis detaljert bruk av tillatelser" - - + "Siste tilgang: %1$s" "Tillatt" - - + "Tillates bare når appen brukes" "Avvist" "Se detaljert bruk" @@ -165,22 +160,6 @@ "Påminnelser om tillatelser" "%s har brukt posisjonen din" "Denne appen har alltid tilgang til posisjonen din. Trykk for å endre." - "Apputvikleren sier at dataene dine kan bli:" - "Hvis du ikke liker hvordan denne apputvikleren bruker dataene dine, kan du avvise tillatelsen." - "Gå til %s for å få mer informasjon." - "Lastet opp til nettskyen" - "Lastet opp til nettskyen når du uttrykkelig tillater det" - "Delt med annonsører eller bedrifter" - "Delt med annonsører eller bedrifter når du uttrykkelig tillater det" - "Brukt til inntektsgenerering" - "Brukt til inntektsgenerering når du uttrykkelig tillater det" - "Lagret og analysert for alltid" - "Lagret og analysert i varigheten du spesifiserer" - - Lagret og analysert i %s uker - Lagret og analysert i 1 uke - - "Apputvikleren spesifiserte ikke hvordan appen bruker dataene dine." "Bare mens appen er i bruk" "Ingen tillatelser er gitt" "Ingen tillatelser er nektet" @@ -205,10 +184,18 @@ "Musikk-appen" "Galleri-appen" "Telefonapp for bilmodus" - "Ringeapp for proxy-tjener" + + "App for anropsutvelgelse" "Følgeapp for ringing" - - + "Assistentapp" + "App for speiling i bilen" "Merk: Hvis du starter enheten din på nytt og har en skjermlås angitt, kan ikke denne appen starte før du låser opp enheten." + "Del feilsøkingsdata" + "Vil du dele detaljerte feilsøkingsdata?" + "%1$s vil laste opp feilsøkingsinformasjon." + "Del feilsøkingsdata" + "%1$s ber om å laste opp en feilrapport fra denne enheten fra %2$s klokken %3$s. Feilrapporter inkluderer personopplysninger om enheten eller opplysninger som er loggført av apper, for eksempel brukernavn, posisjonsdata, enhetsidentifikatorer og nettverksinformasjon. Du bør bare dele feilrapporter med personer og apper du stoler på. Vil du gi %4$s tillatelse til å laste opp en feilrapport?" + "Tillat" + "Avvis" diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml index 6129fbd36..bb93a6465 100644 --- a/res/values-ne/strings.xml +++ b/res/values-ne/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "पछिल्लो १५ मिनेटमा सबैभन्दा बढी प्रयोग गरिएको अनुमति" "पछिल्लो १ मिनेटमा सबैभन्दा बढी प्रयोग गरिएको अनुमति" "अनुप्रयोगहरू" - - - - + "यसअनुसार फिल्टर गरिएको: %1$s" + "फिल्टर हटाउनुहोस्" "यसअनुसार फिल्टर गर्नुहोस्" "अनुमतिअनुसार फिल्टर गर्नुहोस्" "सबैभन्दा धेेरै प्रयोग गरिएको अनुमति" "सबैभन्दा धेरै पटक पहुँच राखिएको" "हालसालैका" - - + "पुनः ताजा गर्नुहोस्" "अनुप्रयोगको अनुमतिको उपयोग" "पहुँच: %1$s पटक। कुल समय: %2$s। पछिल्लो पटक %3$s अघि प्रयोग गरिएको।" "पहुँच: %1$s पटक। पछिल्लो पटक %2$s अघि प्रयोग गरिएको।" @@ -137,11 +134,9 @@ "%1$s ले %3$s पहिले तपाईंको %2$s माथि पहुँच राख्यो।" "%1$sतपाईंको %2$sमाथि पहुँच राखेको छैन।" "अनुमतिको विस्तृत उपयोग हेर्नुहोस्" - - + "पछिल्लो पटक पहुँच राखिएको समय: %1$s" "अनुमति दिइएको" - - + "प्रयोगमा भएका बेला मात्र अनुमति दिइन्छ" "अस्वीकार गरिएको" "उयोगसम्बन्धी विस्तृत जानकारी हेर्नुहोस्" @@ -165,22 +160,6 @@ "अनुमतिसम्बन्धी रिमाइन्डरहरू" "%s ले तपाईंको स्थान प्रयोग गरिरहेको छ" "यो अनुप्रयोगले सधैँ तपाईंको स्थान प्रयोग गर्न सक्छ। बदल्न ट्याप गर्नुहोस्‌।" - "अनुप्रयोगको विकासकर्ताले भनेअनुसार तपाईंको डेटा निम्न प्रयोजनका लागि प्रयोग गर्न सकिन्छ:" - "तपाईंलार्इ यो अनुप्रयोगका विकासकर्ताले तपाईंको डेटा प्रयोग गर्ने तरिका मन पर्दैन भने तपाईं अनुमति नदिन सक्नुहुन्छ।" - "थप जानकारीका लागि %s मा जानुहोस्।" - "क्लाउडमा अपलोड गरिएको" - "तपाईंले स्पष्ट रूपमा अनुमति दिँदा क्लाउडमा अनलोड गरिन्छ" - "विज्ञापनदाता र व्यवसायसँग आदान प्रदान गरिन्छ" - "तपाईंले स्पष्ट रूपमा अनुमति दिँदा विज्ञापनदाता र व्यवसायसँग आदान प्रदान गरिन्छ" - "मुद्रीकरणका लागि प्रयोग गरिएको" - "तपाईंले स्पष्ट रूपमा अनुमति दिँदा मुद्रीकरणका लागि प्रयोग गरिन्छ।" - "सधैँका लागि सुरक्षित र विश्लेषण गरिन्छ" - "तपाईंले तोक्नुभएको अवधिका लागि सुरक्षित र विश्लेषण गरिएको" - - %s हप्ताका लागि सुरक्षित र विश्लेषण गरिएको - १ हप्ताका लागि सुरक्षित र विश्लेषण गरिएको - - "उक्त अनुप्रयोगको विकासकर्ताले अनुप्रयोगले तपाईंको डेटा प्रयोग गर्ने तरिका तोकेका थिएनन्।" "अनुप्रयोग प्रयोगमा भएको बेला मात्र" "कुनै पनि अनुमति छैन" "कुनै पनि अनुमति अस्वीकार गरिएको छैन" @@ -205,10 +184,18 @@ "सङ्गीत अनुप्रयोग" "ग्यालरी अनुप्रयोग" "कार मोड नामक फोन अनुप्रयोग" - "प्रोक्सी कल गर्ने अनुप्रयोग" + + "कललाई स्क्रिनमा देखाउने अनुप्रयोग" "सहयोगी अनुप्रयोगलाई कल गर्नु…" - - + "सहायक अनुप्रयोग" + "कारको प्रोजेक्सनको अनुप्रयोग" "टिपोट: तपाईंले आफ्नो यन्त्र पुनः सुरु गर्नुभयो र त्यसमा स्क्रिन लक सेट गरिएको छ भने तपाईंले आफ्नो यन्त्र अनलक नगरेसम्म यो अनुप्रयोग सुरु हुन सक्दैन।" + "डिबग प्रक्रियासम्बन्धी डेटा आदान प्रदान गर्नुहोस्" + "डिबग प्रक्रियाको विस्तृत डेटा आदान प्रदान गर्ने?" + "%1$s डिबग प्रक्रियासम्बन्धी जानकारी अपलोड गर्न चाहन्छ।" + "डिबग प्रक्रियासम्बन्धी डेटा आदान प्रदान गर्नुहोस्" + "%1$s ले %2$s %3$s मा यो यन्त्रबाट लिएको बगको रिपोर्ट अपलोड गर्ने अनुरोध गर्दै छ। बग रिपोर्टमा प्रयोगकर्ताका नाम, स्ठानसम्बन्धी डेटा, यन्त्रका पहिचानकर्ता र नेटवर्कसम्बन्धी जानकारी जस्ता तपाईंको यन्त्रको व्यक्तिगत जानकारी वा अनुप्रयोगले लग गरेको जानकारी समावेश छ। तपाईंलाई यो जानकारी दिँदा फरक पर्दैन जस्तो लाग्ने विश्वसनीय मान्छे वा अनुप्रयोगसँग मात्र बग रिपोर्टहरू आदान प्रदान गर्नुहोस्। %4$s लाई बग रिपोर्ट अपलोड गर्न दिने हो?" + "अनुमति दिनुहोस्" + "अनुमति नदिनुहोस्" diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml index 28aa27719..03b8d4d87 100644 --- a/res/values-nl/strings.xml +++ b/res/values-nl/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "Top machtigingsgebruik in het afgelopen kwartier" "Top machtigingsgebruik in de afgelopen minuut" "Apps" - - - - + "Gefilterd op: %1$s" + "Filter verwijderen" "Filteren op" "Filteren op machtigingen" "Meeste machtigingen" "Meeste toegangsacties" "Recent" - - + "Vernieuwen" "Gebruik van app-machtigingen" "Toegang: %1$s keer. Totale duur: %2$s. Laatst gebruikt: %3$s geleden." "Toegang: %1$s keer. Laatst gebruikt: %2$s geleden." @@ -137,11 +134,9 @@ "%1$s heeft %3$s geleden toegang tot je %2$s gehad." "%1$s heeft geen toegang verkregen tot je %2$s." "Gedetailleerd machtigingsgebruik weergeven" - - + "Laatste keer geopend: %1$s" "Toegestaan" - - + "Alleen toegestaan tijdens gebruik" "Geweigerd" "Gedetailleerd gebruik bekijken" @@ -165,22 +160,6 @@ "Herinneringen voor machtigingen" "%s maakt gebruik van je locatie" "Deze app heeft altijd toegang tot je locatie. Tik om dit te wijzigen." - "Volgens de app-ontwikkelaar kan er het volgende gebeuren met je gegevens:" - "Als je het niet eens bent met de manier waarop deze app-ontwikkelaar je gegevens gebruikt, kun je de machtiging weigeren." - "Ga naar %s voor meer informatie." - "Geüpload naar de cloud" - "Geüpload naar de cloud wanneer je dit expliciet toestaat" - "Gedeeld met adverteerders of bedrijven" - "Gedeeld met adverteerders of bedrijven wanneer je dit expliciet toestaat" - "Gebruikt voor inkomstenwerving" - "Gebruikt voor inkomstenwerving wanneer je dit expliciet toestaat" - "Zonder eindlimiet opgeslagen en geanalyseerd" - "Opgeslagen en geanalyseerd voor een duur die jij specificeert" - - %s weken opgeslagen en geanalyseerd - Eén week opgeslagen en geanalyseerd - - "De app-ontwikkelaar heeft niet gespecificeerd hoe de app je gegevens gebruikt." "Alleen terwijl de app wordt gebruikt" "Geen machtigingen toegestaan" "Geen machtigingen geweigerd" @@ -205,10 +184,18 @@ "Muziek-app" "Galerij-app" "Telefoon-app voor automodus" - "App voor proxy-gesprekken" + + "App voor gesprekken screenen" "Bijbehorende app voor bellen" - - + "App voor assistentie" + "Autoprojectie-app" "Opmerking: Als je het apparaat opnieuw opstart en een schermvergrendeling hebt ingesteld, kan deze app pas worden gestart nadat je het apparaat hebt ontgrendeld." + "Foutopsporingsgegevens delen" + "Gedetailleerde foutopsporingsgegevens delen?" + "%1$s wil foutopsporingsinformatie uploaden." + "Foutopsporingsgegevens delen" + "%1$s wil een bugrapport van dit apparaat uploaden dat is gemaakt op %2$s om %3$s. Bugrapporten omvatten persoonsgegevens over je apparaat of gegevens die zijn geregistreerd door apps, zoals gebruikersnamen, locatiegegevens, apparaat-ID\'s en netwerkgegevens. Deel alleen bugrapporten met mensen en apps die je met deze informatie vertrouwt. Wil je %4$s toestaan een bugrapport te uploaden?" + "Toestaan" + "Weigeren" diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml index 18d761de5..e22a1c7bb 100644 --- a/res/values-or/strings.xml +++ b/res/values-or/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "ଗତ 15 ମିନିଟ୍‍ରେ ବ୍ୟବହୃତ ହୋଇଥିବା ଶୀର୍ଷ ଅନୁମତି" "ଗତ 1 ଘଣ୍ଟାରେ ବ୍ୟବହୃତ ହୋଇଥିବା ଶୀର୍ଷ ଅନୁମତି" "ଆପ୍ସ" - - - - + "%1$s ଦ୍ବାରା ଫିଲ୍ଟର୍ କରାଯାଇଛି" + "ଫିଲ୍ଟର୍‌କୁ କାଢ଼ିଦିଅନ୍ତୁ" "ଏହି ଅନୁସାରେ ଫିଲ୍ଟର୍ କରନ୍ତୁ" "ଅନୁମତି ଅନୁଯାୟୀ ଫିଲ୍ଟର୍ କରନ୍ତୁ" "ଅଧିକ ଅନୁମତିଗୁଡିକ" "ସର୍ବାଧିକ ଆକ୍ସେସ୍‍ଗୁଡିକ" "ସମ୍ପ୍ରତି" - - + "ରିଫ୍ରେଶ୍ କରନ୍ତୁ" "ଆପ୍‍ ଅନୁମତି ବ୍ୟବହାର" "ଆକ୍ସେସ୍‍: %1$sଥର। ସମୁଦାୟ ଅବଧି: %2$s। ଅନ୍ତିମ ଥର %3$s ପୂର୍ବେ ବ୍ୟବହୃତ ହୋଇଥିଲା।" "ଆକ୍ସେସ୍‍: %1$sଥର। ଅନ୍ତିମ ଥର %2$s ପୂର୍ବେ ବ୍ୟବହୃତ ହୋଇଥିଲା।" @@ -137,11 +134,9 @@ "%1$s %3$s ପୂର୍ବେ ଆପଣଙ୍କ %2$s ଆକ୍ସେସ୍‍ କରିିିିଥିଲେ।" "%1$s ଆପଣଙ୍କ %2$s ଆକ୍ସେସ୍‍ ନାହିଁ।" "ବିସ୍ତୃତ ଅନୁମତି ବ୍ୟବହାର ଦେଖନ୍ତୁ" - - + "ଶେଷ ଥର ପାଇଁ ଆକ୍ସେସ୍ କରାଯାଇଛି: %1$s" "ଅନୁମୋଦିତ" - - + "କେବଳ ବ୍ୟବହାର ପାଇଁ ଅନୁମତି ଦିଆଯାଇଛି" "ପ୍ରତ୍ୟାଖ୍ୟାନ କରାଗଲା" "ବିସ୍ତାରିତ ବ୍ୟବହାର ଦେଖନ୍ତୁ" @@ -165,22 +160,6 @@ "ଅନୁମତି ରିମାଇଣ୍ଡର୍" "%s ଆପଣଙ୍କ ଲୋକେସନ୍ ବ୍ୟବହାର କରୁଛନ୍ତି" "ଏହି ଆପ୍ ସବୁବେଳେ ଆପଣଙ୍କ ଲୋକେସନ୍ ଆକ୍ସେସ୍ କରିପାରିବ। ବଦଳାଇବା ପାଇଁ ଟାପ୍ କରନ୍ତୁ" - "ଆପ୍‍ ଡେଭେଲପର୍‍ କୁହେ ଆପଣଙ୍କ ଡାଟା ହୁଏତ:" - "ଯଦି ଆପଣ ଏହି ଆପ୍‍ ଡେଭେଲପର୍‍ ଆପଣଙ୍କ ଡାଟା କିପରି ବ୍ୟବହାର କରୁଛନ୍ତି ତାହା ପସନ୍ଦ କରୁ ନାହାଁନ୍ତି ତେବେ ଆପଣ ଅନୁମତି ଅଗ୍ରାହ୍ୟ କରିପାରିବେ।" - "ଅଧିକ ସୂଚନା ପାଇଁ %sକୁ ଯାଆନ୍ତୁ" - "କ୍ଲାଉଡ୍‍କୁ‍ ଅପ୍‍‍‍‍‍ଲୋଡ୍‍ ହୋଇଛି" - "ଯେତେବେଳେ ଆପଣ ଏହାକୁ ସ୍ପଷ୍ଟଭାବରେ ଅନୁମତି କରିବେ ସେତେବେଳେ ଆପଣ କ୍ଲାଉଡ୍‍କୁ ଅପ୍‍‍‍‍‍‍‍ଲୋଡ୍‍‍‍ ହେବ" - "ବିଜ୍ଞାପନଦାତା କିମ୍ବା ବ୍ୟବସାୟ ସହ ସେୟାର୍‍ ହୋଇଛି" - "ଯେତେବେଳେ ଆପଣ ଏହାକୁ ସ୍ପଷ୍ଟଭାବରେ ଅନୁମତି କରିବେ ସେତେବେଳେ ବିଜ୍ଞାପନଦାତା ବା ବ୍ୟବସାୟଗୁଡିକ ସହ ସେୟାର୍‍ କରାଯିବ" - "ମୋନେଟାଇଜେସନ୍‍ ପାଇଁ ବ୍ୟବହୃତ ହୋଇଛି" - "ଯେତେବେଳେ ଆପଣ ସ୍ପଷ୍ଟଭାବରେ ଏହାକୁ ଅନୁମତି ଲରିଏବ ମୋନେଟାଇଜେସନ୍‍ ପାଇଁ ବ୍ୟବହୃତ ହେବ" - "ସେଭ୍‍ ହୋଇଛି ଏବଂ ସର୍ବଦା ପାଇଁ ବ୍ୟାଖ୍ୟା କରାଯାଇଛି" - "ଆପଣ ନିର୍ଦ୍ଧିଷ୍ଟ କରିଥିବା ଏକ ଅବଧି ପାଇଁ ସେଭ୍‍ ହେବା ସହ ବ୍ୟାଖ୍ୟା କରାଯାଇଛି" - - %s ସପ୍ତାହ ପାଇଁ ସେଭ୍‍ ହେବା ସହ ବ୍ୟାଖ୍ୟା କରାଯାଇଛି - 1 ସପ୍ତାହ ପାଇଁ ସେଭ୍‍ ହେବା ସହ ବ୍ୟାଖ୍ୟା କରାଯାଇଛି - - "ଆପ୍‍ ଆପଣଙ୍କ ଡାଟା କିପରି ବ୍ୟବହାର କରେ ଏହି ଆପ୍‍ ଡେଭେଲପର୍‍ ନିର୍ଦ୍ଧିଷ୍ଟ କରି ନାହାଁନ୍ତି।" "କେବଳ ଆପ୍‍ ବ୍ୟବହାରରେ ରହିଥିବା ବେଳେ" "କୌଣସି ଅନୁମତି ଦିଆଯାଇ ନାହିଁ" "କୌଣସି ଅନୁମତି ଅଗ୍ରାହ୍ୟ କରାଯାଇନାହିଁ" @@ -205,10 +184,18 @@ "Music ଆପ୍‍" "Gallery ଆପ୍‍" "କାର୍ ମୋଡ୍ ଫୋନ୍ ଆପ୍" - "ପ୍ରକ୍ସି କଲିଂ ଆପ୍" + + "କଲ୍ ସ୍କ୍ରିନିଂ ଆପ୍" "ସହଯୋଗୀ ଆପ୍‌କୁ କଲ୍ କରନ୍ତୁ" - - + "ସହାୟକ ଆପ୍‌" + "କାର୍ ପ୍ରୋଜେକ୍ସନ୍ ଆପ୍" "ଟିପ୍ପଣୀ: ଯଦି ଆପଣ ଆପଣଙ୍କ ଡିଭାଇସ୍ ରିଷ୍ଟାର୍ଟ କରିବେ ଏବଂ ଏକ ସ୍କ୍ରିନ୍ ଲକ୍ ସେଟ୍ ହେବ, ଆପଣଙ୍କ ଡିଭାଇସ୍ ଅନ୍‌ଲକ୍ ନହେବା ପର୍ଯ୍ୟନ୍ତ ଏହି ଆପ୍ ଆରମ୍ଭ ହୋଇପାରିବ ନାହିଁ।" + "ଡିବଗିଂ ଡାଟା ସେୟାର୍ କରନ୍ତୁ" + "ବିସ୍ତୃତ ଡିବଗିଂ ଡାଟା ସେୟାର୍ କରିବେ?" + "%1$s ଡିବଗିଂ ସୂଚନା ଅପ୍‌ଲୋଡ୍ କରିବାକୁ ଚାହାନ୍ତି।" + "ଡିବଗିଂ ଡାଟା ସେୟାର୍ କରନ୍ତୁ" + "%1$s %2$s %3$sରେ ଏହି ଡିଭାଇସ୍‌ରୁ ନିଆଯାଇଥିବା ଏକ ବଗ୍ ରିପୋର୍ଟ ଅପ୍‌ଲୋଡ୍ କରିବାକୁ ଅନୁରୋଧ କରିଛି। ବଗ୍ ରିପୋର୍ଟରେ ଆପଣଙ୍କ ଡିଭାଇସ୍ ସମ୍ବନ୍ଧରେ ବ୍ୟକ୍ତିଗତ ସୂଚନା ବା ଆପ୍ସ ଲଗ୍‌ଇନ୍ ସମୟରେ ଦେଇଥିବା ବ୍ୟକ୍ତିଗତ ସୂଚନା ଉଦାହରଣ ସ୍ବରୂପ ଉପଯୋଗକର୍ତ୍ତାଙ୍କ ନାମ, ଲୋକେସନ୍, ଡିଭାଇସ୍ ଚିହ୍ନଟକାରୀ, ଏବଂ ନେଟ୍‍ୱର୍କ ସୂଚନା ଅନ୍ତର୍ଭୂକ୍ତ ରହିଛି। ଏହି ସୂଚନା ସେୟାର୍ କରିବା ପାଇଁ ଆପଣ ଯାହାଙ୍କୁ ଭରସା କରୁଛନ୍ତି କେବଳ ସେହି ଲୋକ ଏବଂ ଆପ୍ସ ସହିତ ବଗ୍ ରିପୋର୍ଟ ସେୟାର୍ କରନ୍ତୁ। ଏକ ବଗ୍ ରିପୋର୍ଟ ଅପ୍‌ଲୋଡ୍ କରିବା ପାଇଁ %4$sକୁ ଅନୁମତି ଦେବେ?" + "ଅନୁମତି ଦିଅନ୍ତୁ" + "ପ୍ରତ୍ୟାଖ୍ୟାନ କରନ୍ତୁ" diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml index 7eaf8dd9e..328a6ddd7 100644 --- a/res/values-pa/strings.xml +++ b/res/values-pa/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "ਪਿਛਲੇ 15 ਮਿੰਟ ਵਿੱਚ ਆਮ ਇਜਾਜ਼ਤ ਵਰਤੋਂ" "ਪਿਛਲੇ 1 ਮਿੰਟ ਵਿੱਚ ਆਮ ਇਜਾਜ਼ਤ ਵਰਤੋਂ" "ਐਪਾਂ" - - - - + "ਇਸ ਮੁਤਾਬਕ ਫਿਲਟਰ ਕੀਤਾ ਗਿਆ: %1$s" + "ਫਿਲਟਰ ਹਟਾਓ" "ਇਸ ਮੁਤਾਬਕ ਫਿਲਟਰ ਕਰੋ" "ਇਜਾਜ਼ਤਾਂ ਮੁਤਾਬਕ ਫਿਲਟਰ ਕਰੋ" "ਸਭ ਤੋਂ ਵੱਧ ਇਜਾਜ਼ਤਾਂ" "ਸਭ ਤੋਂ ਵੱਧ ਪਹੁੰਚ" "ਹਾਲੀਆ" - - + "ਰਿਫ੍ਰੈਸ਼ ਕਰੋ" "ਐਪ ਇਜਾਜ਼ਤਾਂ ਵਰਤੋ" "ਪਹੁੰਚ: %1$s ਵਾਰ। ਕੁੱਲ ਮਿਆਦ: %2$s। ਪਿਛਲੀ ਵਾਰ %3$s ਪਹਿਲਾਂ ਵਰਤੀ ਗਈ।" "ਪਹੁੰਚ: %1$s ਵਾਰ। ਪਿਛਲੀ ਵਾਰ %2$s ਪਹਿਲਾਂ ਵਰਤੀ ਗਈ।" @@ -137,11 +134,9 @@ "%1$s ਨੇ %3$s ਪਹਿਲਾਂ ਤੁਹਾਡੇ %2$s ਤੱਕ ਪਹੁੰਚ ਕੀਤੀ।" "%1$s ਨੇ ਤੁਹਾਡੇ %2$s ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ।" "ਇਜਾਜ਼ਤਾਂ ਦੀ ਵਰਤੋਂ ਵੇਰਵੇ-ਸਹਿਤ ਦੇਖੋ" - - + "ਪਿਛਲੀ ਵਾਰ ਪਹੁੰਚ: %1$s" "ਮਨਜ਼ੂਰਸ਼ੁਦਾ" - - + "ਸਿਰਫ਼ ਵਰਤੋਂ \'ਚ ਹੋਣ \'ਤੇ ਕਰਨ ਦਿੱਤਾ ਜਾਂਦਾ" "ਗੈਰ-ਮਨਜ਼ੂਰਸ਼ੁਦਾ" "ਵੇਰੇਵੇ ਸਹਿਤ ਵਰਤੋਂ ਦੇਖੋ" @@ -165,22 +160,6 @@ "ਇਜਾਜ਼ਤਾਂ ਦੀਆਂ ਯਾਦ-ਸੂਚਨਾਵਾਂ" "%s ਨੇ ਤੁਹਾਡੀ ਟਿਕਾਣਾ ਜਾਣਕਾਰੀ ਵਰਤੀ ਹੈ" "ਇਹ ਐਪ ਹਮੇਸ਼ਾਂ ਤੁਹਾਡੀ ਟਿਕਾਣਾ ਜਾਣਕਾਰੀ \'ਤੇ ਪਹੁੰਚ ਕਰ ਸਕਦੀ ਹੈ। ਬਦਲਣ ਲਈ ਟੈਪ ਕਰੋ।" - "ਐਪ ਵਿਕਾਸਕਾਰ ਦਾ ਕਹਿਣਾ ਹੈ ਕਿ ਸ਼ਾਇਦ ਤੁਹਾਡੇ ਡਾਟੇ ਨੂੰ:" - "ਜੇ ਤੁਹਾਨੂੰ ਐਪ ਵਿਕਾਸਕਾਰ ਵੱਲੋਂ ਤੁਹਾਡਾ ਡਾਟਾ ਵਰਤੇ ਜਾਣਾ ਪਸੰਦ ਨਹੀਂ ਹੈ, ਤਾਂ ਤੁਸੀਂ ਇਜਾਜ਼ਤ ਨੂੰ ਅਸਵੀਕਾਰ ਕਰ ਸਕਦੇ ਹੋ।" - "ਹੋਰ ਜਾਣਕਾਰੀ ਲਈ %s \'ਤੇ ਜਾਓ।" - "ਕਲਾਊਡ \'ਤੇ ਅੱਪਲੋਡ ਕੀਤਾ ਜਾਂਦਾ ਹੈ" - "ਤੁਹਾਡੇ ਵੱਲੋਂ ਸਾਫ਼ ਤੌਰ \'ਤੇ ਇੰਝ ਕਰਨ ਦੇਣ ਕਰਕੇ ਕਲਾਊਡ \'ਤੇ ਅੱਪਲੋਡ ਕੀਤਾ ਜਾਂਦਾ ਹੈ" - "ਵਿਗਿਆਪਨਦਾਤਾਵਾਂ ਜਾਂ ਕਾਰੋਬਾਰਾਂ ਨਾਲ ਸਾਂਝਾ ਕੀਤਾ ਜਾਂਦਾ ਹੈ" - "ਤੁਹਾਡੇ ਵੱਲੋਂ ਸਾਫ਼ ਤੌਰ \'ਤੇ ਇੰਝ ਕਰਨ ਦੇਣ ਕਰਕੇ ਵਿਗਿਆਪਨਦਾਤਾਵਾਂ ਜਾਂ ਕਾਰੋਬਾਰਾਂ ਨਾਲ ਸਾਂਝਾ ਕੀਤਾ ਜਾਂਦਾ ਹੈ" - "ਮੁਦਰੀਕਰਨ ਲਈ ਵਰਤਿਆ ਜਾਂਦਾ ਹੈ" - "ਤੁਹਾਡੇ ਵੱਲੋਂ ਸਾਫ਼ ਤੌਰ \'ਤੇ ਇੰਝ ਕਰਨ ਦੇਣ ਕਰਕੇ ਇਹ ਮੁਦਰੀਕਰਨ ਲਈ ਵਰਤਿਆ ਜਾਂਦਾ ਹੈ" - "ਹਮੇਸ਼ਾਂ ਰੱਖਿਅਤ ਕੀਤਾ ਅਤੇ ਵਿਸ਼ਲੇਸ਼ਣ ਕੀਤਾ ਜਾਂਦਾ ਹੈ" - "ਤੁਹਾਡੇ ਵੱਲੋਂ ਦੱਸੀ ਇੱਕ ਮਿਆਦ ਲਈ ਰੱਖਿਅਤ ਕੀਤਾ ਅਤੇ ਵਿਸ਼ਲੇਸ਼ਣ ਕੀਤਾ ਜਾਂਦਾ ਹੈ" - - %s ਹਫ਼ਤੇ ਲਈ ਰੱਖਿਅਤ ਕੀਤਾ ਅਤੇ ਵਿਸ਼ਲੇਸ਼ਣ ਕੀਤਾ ਜਾਂਦਾ ਹੈ - %s ਹਫ਼ਤਿਆਂ ਲਈ ਰੱਖਿਅਤ ਕੀਤਾ ਅਤੇ ਵਿਸ਼ਲੇਸ਼ਣ ਕੀਤਾ ਜਾਂਦਾ ਹੈ - - "ਐਪ ਵਿਕਾਸਕਾਰ ਨੇ ਐਪ ਵੱਲੋਂ ਤੁਹਾਡਾ ਡਾਟਾ ਵਰਤੇ ਜਾਣ ਬਾਰੇ ਕੁਝ ਨਹੀਂ ਦੱਸਿਆ ਹੈ।" "ਸਿਰਫ਼ ਐਪ ਵਰਤੇ ਜਾਣ ਵੇਲੇ" "ਕੋਈ ਇਜਾਜ਼ਤਾਂ ਨਹੀਂ ਦਿੱਤੀਆਂ ਗਈਆਂ ਹਨ" "ਕੋਈ ਇਜਾਜ਼ਤਾਂ ਅਸਵੀਕਾਰ ਨਹੀਂ ਕੀਤੀਆਂ ਗਈਆਂ ਹਨ" @@ -205,10 +184,18 @@ "ਸੰਗੀਤ ਐਪ" "ਗੈਲਰੀ ਐਪ" "ਕਾਰ ਮੋਡ ਫ਼ੋਨ ਐਪ" - "ਪ੍ਰੌਕਸੀ ਕਾਲਿੰਗ ਐਪ" + + "ਕਾਲ ਸਕ੍ਰੀਨਿੰਗ ਐਪ" "ਕਾਲ ਸੰਬੰਧੀ ਐਪ" - - + "ਸਹਾਇਕ ਐਪ" + "ਕਾਰ ਦੀ ਯੋਜਨਾਬੰਦੀ ਐਪ" "ਨੋਟ-ਕਥਨ: ਜੇਕਰ ਤੁਸੀਂ ਆਪਣੇ ਡੀਵਾਈਸ ਨੂੰ ਮੁੜ-ਸ਼ੁਰੂ ਕਰਦੇ ਹੋ ਅਤੇ ਸਕ੍ਰੀਨ ਲਾਕ ਸੈੱਟ ਕੀਤਾ ਹੋਇਆ ਹੈ, ਤਾਂ ਇਹ ਐਪਾ ਤੁਹਾਡੇ ਵੱਲੋਂ ਆਪਣੇ ਡੀਵਾਈਸ ਨੂੰ ਅਣਲਾਕ ਕੀਤੇ ਨਾ ਹੋਣ ਤੱਕ ਸ਼ੁਰੂ ਨਹੀਂ ਹੋਵੇਗੀ।" + "ਡੀਬੱਗਿੰਗ ਡਾਟਾ ਸਾਂਝਾ ਕਰੋ" + "ਕੀ ਵੇਰਵੇ ਸਮੇਤ ਡੀਬੱਗਿੰਗ ਡਾਟਾ ਸਾਂਝਾ ਕਰਨਾ ਹੈ?" + "%1$s ਡੀਬੱਗਿੰਗ ਜਾਣਕਾਰੀ ਨੂੰ ਅੱਪਲੋਡ ਕਰਨਾ ਚਾਹੁੰਦੀ ਹੈ।" + "ਡੀਬੱਗਿੰਗ ਡਾਟਾ ਸਾਂਝਾ ਕਰੋ" + "%1$s ਇਸ ਡੀਵਾਈਸ ਤੋਂ %2$s ਨੂੰ %3$s ਵਜੇ ਬਣਾਈ ਗਈ ਬੱਗ ਰਿਪੋਰਟ ਨੂੰ ਅੱਪਲੋਡ ਕਰਨ ਲਈ ਬੇਨਤੀ ਕਰ ਰਹੀ ਹੈ। ਬੱਗ ਰਿਪੋਰਟਾਂ ਵਿੱਚ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਜਾਂ ਐਪਾਂ ਰਾਹੀਂ ਲੌਗ ਕਰਨ ਬਾਰੇ ਨਿੱਜੀ ਜਾਣਕਾਰੀ ਸ਼ਾਮਲ ਹੈ, ਉਦਾਹਰਨ ਲਈ, ਵਰਤੋਂਕਾਰ ਨਾਮ, ਟਿਕਾਣਾ ਡਾਟਾ, ਡੀਵਾਈਸ ਪਛਾਣਕਰਤਾ ਅਤੇ ਨੈੱਟਵਰਕ ਜਾਣਕਾਰੀ। ਇਸ ਜਾਣਕਾਰੀ ਨਾਲ ਸਿਰਫ਼ ਆਪਣੇ ਭਰੋਸੇਯੋਗ ਲੋਕਾਂ ਅਤੇ ਐਪਾਂ ਨਾਲ ਬੱਗ ਰਿਪੋਰਟਾਂ ਸਾਂਝੀਆਂ ਕਰੋ। ਕੀ %4$s ਨੂੰ ਬੱਗ ਰਿਪੋਰਟ ਅੱਪਲੋਡ ਕਰਨ ਦੇਣੀ ਹੈ?" + "ਕਰਨ ਦਿਓ" + "ਨਾ ਕਰਨ ਦਿਓ" diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml index 678c7113b..931d69b0e 100644 --- a/res/values-pl/strings.xml +++ b/res/values-pl/strings.xml @@ -4,9 +4,9 @@ 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. @@ -116,17 +116,14 @@ "Najczęściej używane w ciągu ostatnich 15 minut" "Najczęściej używane w ciągu ostatniej minuty" "Aplikacje" - - - - + "Filtrowane według: %1$s" + "Usuń filtr" "Filtruj według" "Filtruj według uprawnień" "Najwięcej uprawnień" "Najczęściej używane" "Ostatnio" - - + "Odśwież" "Użycie uprawnień aplikacji" "Dostęp: %1$s razy. Całkowity czas trwania: %2$s. Ostatnio użyto %3$s temu." "Dostęp: %1$s razy. Ostatnio użyto %2$s temu." @@ -139,11 +136,9 @@ "Aplikacja %1$s użyła dostępu do: %2$s %3$s temu." "Aplikacja %1$s nie korzysta z: %2$s." "Wyświetl szczegółowe użycie uprawnień" - - + "Ostatnie użycie: %1$s" "Dozwolone" - - + "Zgoda na dostęp tylko podczas używania" "Niedozwolone" "Zobacz szczegółowe informacje o użyciu" @@ -175,24 +170,6 @@ "Przypomnienia o uprawnieniach" "Aplikacja %s używa Twojej lokalizacji" "Ta aplikacja może zawsze uzyskać dostęp do Twojej lokalizacji. Kliknij, by to zmienić." - "Zgodnie z informacjami od dewelopera aplikacji Twoje dane mogą być:" - "Jesli nie podoba Ci się sposób, w jaki deweloper tej aplikacji używa Twoich danych, możesz nie przyznawać uprawnień." - "Otwórz aplikację %s, by dowiedzieć się więcej." - "Przesyłane do chmury." - "Przesyłane do chmury, gdy na to wyraźnie zezwolisz." - "Udostępniane reklamodawcom lub firmom." - "Udostępniane reklamodawcom lub firmom, gdy na to wyraźnie zezwolisz." - "Używane do generowania przychodu." - "Używane do generowania przychodu, gdy wyraźnie na to zezwolisz." - "Zapisane trwale i zawsze analizowane." - "Zapisywane i analizowane przez określony przez Ciebie czas." - - Zapisywane i analizowane przez %s tygodnie - Zapisywane i analizowane przez %s tygodni - Zapisywane i analizowane przez %s tygodnia - Zapisywane i analizowane przez tydzień. - - "Deweloper aplikacji nie określił, jak aplikacja używa Twoich danych." "Tylko podczas używania aplikacji" "Nie przyznano żadnych uprawnień" "Nie odmówiono żadnych uprawnień" @@ -217,10 +194,18 @@ "Aplikacja Muzyka" "Aplikacja Galeria" "Aplikacja na telefon, tryb samochodowy" - "Aplikacja wywołująca proxy" + + "Aplikacja do filtrowania połączeń" "Aplikacja towarzysząca połączeniom" - - + "Aplikacja asystująca" + "Aplikacja do wyświetlania treści w samochodzie" "Uwaga: Po ponownym uruchomieniu urządzenia z ustawioną blokadą ekranu ta aplikacja będzie mogła uruchomić się dopiero wtedy, gdy odblokujesz urządzenie." + "Udostępnianie danych debugowania" + "Udostępnić szczegółowe dane debugowania?" + "%1$s chce przesłać informacje debugowania." + "Udostępnianie danych debugowania" + "%1$s prosi o zezwolenie na przesłanie raportu o błędzie z tego urządzenia. Raport utworzono %2$s%3$s. Raporty o błędach zawierają dane prywatne powiązane z Twoim urządzeniem lub zarejestrowane w aplikacjach, na przykład nazwy użytkowników, dane o lokalizacji, identyfikatory urządzeń i informacje o sieciach. Raporty o błędach zawierające te informacje udostępniaj tylko osobom i aplikacjom, którym ufasz. Zezwolić aplikacji %4$s na przesłanie raportu o błędzie?" + "Zezwól" + "Odmów" diff --git a/res/values-pt-rBR/strings.xml b/res/values-pt-rBR/strings.xml index 63e4612d5..ff38f6f47 100644 --- a/res/values-pt-rBR/strings.xml +++ b/res/values-pt-rBR/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "Permissão mais usada nos últimos 15 minutos" "Permissão mais usada no último minuto" "Apps" - - - - + "Filtrado por: %1$s" + "Remover filtro" "Filtrar por" "Filtrar por permissões" "Maior número de permissões" "Maior número de acessos" "Recentes" - - + "Atualizar" "Uso de permissões do app" "Acesso: %1$s vezes. Duração total: %2$s. Última utilização: %3$s atrás." "Acesso: %1$s vezes. Última utilização: %2$s atrás." @@ -137,11 +134,9 @@ "O app %1$s acessou sua permissão de %2$s %3$s atrás." "O app %1$s não acessou seu %2$s." "Ver uso detalhado das permissões" - - + "Último acesso: %1$s" "Permitido" - - + "Permitido apenas quando em uso" "Negado" "Ver uso detalhado" @@ -165,22 +160,6 @@ "Lembretes de permissões" "O app %s está usando sua localização" "Este app pode acessar sua localização a qualquer momento. Toque para alterar." - "O desenvolvedor do app avisa que seus dados podem ser:" - "Se não estiver satisfeito com o uso que o desenvolvedor faz dos seus dados, negue a permissão." - "Acesse %s para ver mais informações." - "enviados para a nuvem;" - "enviados para a nuvem quando há sua permissão explícita;" - "compartilhados com anunciantes ou empresas;" - "compartilhados com anunciantes ou empresas quando há sua permissão explícita;" - "usados para monetização;" - "usados para monetização quando há sua permissão explícita;" - "salvos e analisados permanentemente;" - "salvos e analisados pela duração especificada por você;" - - salvos e analisados por %s semana; - salvos e analisados por %s semanas;​ - - "O desenvolvedor do app não especificou como seus dados são usados." "Apenas enquanto o app estiver em uso" "Nenhuma permissão autorizada" "Nenhuma permissão negada" @@ -205,10 +184,18 @@ "App de música" "App de galeria" "App Telefone no modo carro" - "App de chamadas de proxy" + + "App identificador de chamadas" "App complementar de chamadas" - - + "App assistivo" + "App de projeção do carro" "Observação: se você reiniciar o dispositivo e tiver um bloqueio de tela definido, não será possível iniciar este app até que você desbloqueie o dispositivo." + "Compartilhar dados de depuração" + "Compartilhar dados detalhados de depuração?" + "Solicitação do %1$s para upload de informações de depuração." + "Compartilhar dados de depuração" + "Há uma solicitação do %1$s para upload de um relatório de bug criado neste dispositivo no dia %2$s, %3$s. Os relatórios de bug incluem informações pessoais do seu dispositivo ou registradas por apps, como nomes de usuário, dados de local, identificadores do dispositivo e informações de rede. Compartilhe relatórios de bugs apenas com pessoas e apps em que você confie para ter acesso a essas informações. Permitir que o %4$s faça upload do relatório de bug?" + "Permitir" + "Negar" diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml index fe0ec38b2..7abf219e6 100644 --- a/res/values-pt-rPT/strings.xml +++ b/res/values-pt-rPT/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "Utiliz. das princ. autorizações nos últ. 15 min" "Utiliz. das principais autorizações no último min" "Aplicações" - - - - + "Filtrado por: %1$s" + "Remover filtro" "Filtrar por" "Filtrar por autorizações" "Maioria de autorizações" "Maioria de acessos" "Recentes" - - + "Atualizar" "Utiliz. de autoriz. da app" "Acesso: %1$s vezes. Duração total: %2$s. Última utilização há %3$s." "Acesso: %1$s vezes. Última utilização há %2$s." @@ -137,11 +134,9 @@ "A aplicação %1$s acedeu ao(à) %2$s%3$s." "A aplicação %1$s não acedeu à sua %2$s." "Ver utilização de autorizações detalhada" - - + "Último acesso: %1$s" "Permitidas" - - + "Apenas permitido durante a utilização" "Recusadas" "Ver a utilização detalhada" @@ -165,22 +160,6 @@ "Lembretes de autorização" "A aplicação %s tem estado a utilizar a sua localização" "Esta aplicação consegue aceder sempre à sua localização. Toque para alterar." - "O programador da aplicação afirma que os seus dados podem ser:" - "Se não gostar da forma como o programador desta aplicação está a utilizar os seus dados, pode recusar a autorização." - "Para mais informações, aceda à aplicação %s." - "Carregados para a nuvem." - "Carregados para a nuvem quando o autorizar explicitamente." - "Partilhados com anunciantes ou empresas." - "Partilhados com anunciantes ou empresas quando o autorizar explicitamente." - "Utilizados para rentabilização." - "Utilizados para rentabilização quando o autorizar explicitamente." - "Guardados e analisados para sempre." - "Guardados e analisados durante o período especificado por si." - - Guardados e analisados durante %s semanas. - Guardados e analisados durante 1 semana. - - "O programador da aplicação não especificou de que forma a aplicação utiliza os seus dados." "Apenas enquanto a aplicação está a ser utilizada" "Nenhuma autorização permitida." "Nenhuma autorização recusada." @@ -205,10 +184,18 @@ "Aplicação de música" "Aplicação de galeria" "Aplic. Telefone modo automóvel" - "Aplicação de chamadas de proxy" + + "Aplic. de filtro de chamadas" "Aplic. associada de chamadas" - - + "Aplicação de assistência" + "Aplicação Car Projection" "Nota: se reiniciar o dispositivo e tiver um bloqueio de ecrã definido, só é possível iniciar esta aplicação quando o dispositivo for desbloqueado." + "Partilhar dados de depuração" + "Pretende partilhar dados de depuração detalhados?" + "A aplicação %1$s pretende carregar informações de depuração." + "Partilhar dados de depuração" + "A aplicação %1$s está a solicitar o carregamento de um relatório de erro a partir deste dispositivo realizado a %2$s à(s) %3$s. Os relatórios de erros incluem informações pessoais acerca do seu dispositivo ou registadas por aplicações, por exemplo, nomes de utilizador, dados de localização, identificadores do dispositivo e informações da rede. Apenas partilhe relatórios de erros com pessoas e aplicações nas quais confia. Permite que a aplicação %4$s carregue um relatório de erro?" + "Permitir" + "Recusar" diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml index 63e4612d5..ff38f6f47 100644 --- a/res/values-pt/strings.xml +++ b/res/values-pt/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "Permissão mais usada nos últimos 15 minutos" "Permissão mais usada no último minuto" "Apps" - - - - + "Filtrado por: %1$s" + "Remover filtro" "Filtrar por" "Filtrar por permissões" "Maior número de permissões" "Maior número de acessos" "Recentes" - - + "Atualizar" "Uso de permissões do app" "Acesso: %1$s vezes. Duração total: %2$s. Última utilização: %3$s atrás." "Acesso: %1$s vezes. Última utilização: %2$s atrás." @@ -137,11 +134,9 @@ "O app %1$s acessou sua permissão de %2$s %3$s atrás." "O app %1$s não acessou seu %2$s." "Ver uso detalhado das permissões" - - + "Último acesso: %1$s" "Permitido" - - + "Permitido apenas quando em uso" "Negado" "Ver uso detalhado" @@ -165,22 +160,6 @@ "Lembretes de permissões" "O app %s está usando sua localização" "Este app pode acessar sua localização a qualquer momento. Toque para alterar." - "O desenvolvedor do app avisa que seus dados podem ser:" - "Se não estiver satisfeito com o uso que o desenvolvedor faz dos seus dados, negue a permissão." - "Acesse %s para ver mais informações." - "enviados para a nuvem;" - "enviados para a nuvem quando há sua permissão explícita;" - "compartilhados com anunciantes ou empresas;" - "compartilhados com anunciantes ou empresas quando há sua permissão explícita;" - "usados para monetização;" - "usados para monetização quando há sua permissão explícita;" - "salvos e analisados permanentemente;" - "salvos e analisados pela duração especificada por você;" - - salvos e analisados por %s semana; - salvos e analisados por %s semanas;​ - - "O desenvolvedor do app não especificou como seus dados são usados." "Apenas enquanto o app estiver em uso" "Nenhuma permissão autorizada" "Nenhuma permissão negada" @@ -205,10 +184,18 @@ "App de música" "App de galeria" "App Telefone no modo carro" - "App de chamadas de proxy" + + "App identificador de chamadas" "App complementar de chamadas" - - + "App assistivo" + "App de projeção do carro" "Observação: se você reiniciar o dispositivo e tiver um bloqueio de tela definido, não será possível iniciar este app até que você desbloqueie o dispositivo." + "Compartilhar dados de depuração" + "Compartilhar dados detalhados de depuração?" + "Solicitação do %1$s para upload de informações de depuração." + "Compartilhar dados de depuração" + "Há uma solicitação do %1$s para upload de um relatório de bug criado neste dispositivo no dia %2$s, %3$s. Os relatórios de bug incluem informações pessoais do seu dispositivo ou registradas por apps, como nomes de usuário, dados de local, identificadores do dispositivo e informações de rede. Compartilhe relatórios de bugs apenas com pessoas e apps em que você confie para ter acesso a essas informações. Permitir que o %4$s faça upload do relatório de bug?" + "Permitir" + "Negar" diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml index 8f5cf99d8..b31a8047d 100644 --- a/res/values-ro/strings.xml +++ b/res/values-ro/strings.xml @@ -4,9 +4,9 @@ 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. @@ -115,17 +115,14 @@ "Cele mai utilizate permisiuni în ultimele 15 min" "Cele mai utilizate permisiuni în ultimul minut" "Aplicații" - - - - + "Filtrat după: %1$s" + "Eliminați filtrul" "Filtrați după" "Filtrați după permisiuni" "Cele mai multe permisiuni" "Cele mai multe accesuri" "Recente" - - + "Actualizați" "Utilizare permisiuni pentru aplicație" "Acces: %1$s ori. Durată totală: %2$s. Ultima utilizare: acum %3$s." "Acces: %1$s ori. Ultima utilizare: acum %2$s." @@ -138,11 +135,9 @@ "Aplicația %1$s a accesat %2$s acum %3$s." "%1$s nu a accesat %2$s." "Afișați utilizarea detaliată a permisiunilor" - - + "Ultima accesare: %1$s" "Permise" - - + "Permis numai în timpul utilizării" "Respinse" "Vedeți detaliile utilizării" @@ -170,23 +165,6 @@ "Mementouri de permisiune" "%s folosește locația dvs." "Această aplicație poate accesa întotdeauna locația dvs. Atingeți ca să modificați." - "Dezvoltatorul aplicației afirmă că datele pot fi:" - "Dacă nu vă place cum folosește dezvoltatorul aplicației datele dvs., îi puteți refuza permisiunea." - "Accesați %s pentru mai multe informații." - "Încărcate în cloud" - "Încărcate în cloud când permiteți în mod explicit" - "Distribuite advertiserilor sau companiilor" - "Distribuite advertiserilor sau companiilor când permiteți explicit" - "Folosite pentru generare de bani" - "Folosite pentru generare de bani când permiteți explicit" - "Salvate și analizate permanent" - "Salvate și analizate pe durata specificată de dvs." - - Salvate și analizate timp de %s săptămâni - Salvate și analizate timp de %s de săptămâni - Salvate și analizate timp de 1 săptămână - - "Dezvoltatorul aplicației nu a specificat cum folosește aplicația datele dvs." "Numai când aplicația este folosită" "Nicio permisiune" "Nu există permisiuni refuzate" @@ -211,10 +189,18 @@ "Aplicația Muzică" "Aplicația Galerie" "Aplicația pentru telefon în modul Mașină" - "Aplicația de apelare proxy" + + "Aplicația de filtrare a apelurilor" "Aplicație partener de apelare" - - + "Aplicație asistent" + "Aplicația pentru proiecția mașinii" "Notă: dacă reporniți telefonul și aveți activată blocarea ecranului, această aplicație nu poate porni până nu deblocați telefonul." + "Trimiteți datele despre remedierea erorilor" + "Trimiteți datele detaliate despre remedierea erorilor?" + "%1$s dorește să încarce informațiile despre remedierea erorilor." + "Trimiteți datele despre remedierea erorilor" + "%1$s solicită încărcarea unui raport de erori de pe acest dispozitiv creat în data de %2$s la %3$s. Rapoartele de erori conțin informații cu caracter personal despre dispozitiv sau înregistrate de aplicații, de exemplu: nume de utilizator, date privind locațiile, identificatori ai dispozitivului și informații despre rețea. Trimiteți rapoarte de erori doar persoanelor și aplicațiilor de încredere. Permiteți %4$s să încarce un raport de erori?" + "Permiteți" + "Refuzați" diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index d226b8141..71cc4048d 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -4,9 +4,9 @@ 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. @@ -116,17 +116,14 @@ "Самые популярные разрешения за последние 15 минут" "Самые популярные разрешения за последнюю минуту" "Приложения" - - - - + "Фильтры: %1$s" + "Удалить фильтр" "Фильтровать по" "Фильтровать по разрешениям" "Популярность" "Количество разрешений" "Недавние" - - + "Обновить" "Использование разрешений" "Сколько раз использовано: %1$s. Общее время использования: %2$s. Последний раз: %3$s назад." "Сколько раз использовано: %1$s. Последний раз: %2$s назад." @@ -139,11 +136,9 @@ "Приложение \"%1$s\" получило доступ к разрешению \"%2$s\" %3$s назад." "Приложение \"%1$s\" не обратилось к следующему разрешению: %2$s." "Показать подробную информацию об использовании разрешений" - - + "Последний раз использовано: %1$s" "Предоставленные разрешения" - - + "Только когда приложение открыто" "Отсутствующие разрешения" "Подробные сведения об использовании" @@ -175,24 +170,6 @@ "Напоминания о разрешениях" "Приложение \"%s\" использовало ваши геоданные" "У этого приложения есть постоянный доступ к сведениям о вашем местоположении. Нажмите, чтобы изменить настройки." - "Разработчик приложения заявляет, что ваши данные могут:" - "Не предоставляйте разрешения, если вы не согласны с тем, как разработчик приложения собирается использовать ваши данные." - "Подробнее об этом можно узнать в приложении \"%s\"." - "Загружаться в облачное хранилище." - "Загружаться в облачное хранилище с вашего явного согласия." - "Предоставляться рекламодателям и коммерческим компаниям." - "Предоставляться рекламодателям и коммерческим компаниям с вашего явного согласия." - "Использоваться в коммерческих целях." - "Использоваться в коммерческих целях с вашего явного согласия." - "Храниться и использоваться для анализа в течение неограниченного времени." - "Храниться и использоваться для анализа на протяжении указанного вами времени." - - Храниться и использоваться для анализа в течение %s недели. - Храниться и использоваться для анализа в течение %s недель. - Храниться и использоваться для анализа в течение %s недель. - Храниться и использоваться для анализа в течение %s недели. - - "Разработчик приложения не указал, как приложение будет использовать ваши данные." "Разрешить только в активном режиме" "Разрешения не предоставлены" "Предоставлены все разрешения" @@ -217,10 +194,18 @@ "Музыка" "Галерея" "Приложение для звонков во время вождения" - "Приложение для звонков через прокси-сервер" + + "Приложение для управления входящими вызовами" "Сопутствующее приложение для звонков" - - + "Помощник" + "Трансляция на экран автомобиля" "Примечание. Если у вас установлена блокировка экрана, после перезагрузки вам потребуется разблокировать устройство, чтобы запустить приложение." + "Отправка данных об отладке" + "Отправка детализированных данных об отладке" + "Приложение \"%1$s\" запрашивает разрешение на загрузку данных об отладке." + "Отправка данных об отладке" + "Приложение \"%1$s\" запрашивает ваше согласие на загрузку с этого устройства отчета об ошибке от %3$s %2$s. Отчет может содержать персональную информацию с устройства или из установленных приложений, например имена пользователей, сведения о местоположении, идентификаторы устройства и данные сети. Мы рекомендуем отправлять отчеты об ошибке только тем приложениям и пользователям, которым вы доверяете. Разрешить приложению \"%4$s\" загрузку отчета об ошибке?" + "Разрешить" + "Запретить" diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml index 9826fb7cc..e3adf4b78 100644 --- a/res/values-si/strings.xml +++ b/res/values-si/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "පසුගිය විනාඩි 15ක් තුළ ඉහළ අවසර භාවිතය" "පසුගිය විනාඩි 1 තුළ ඉහළ අවසර භාවිතය" "යෙදුම්" - - - - + "මේ අනුව පෙරහන්න: %1$s" + "පෙරහන ඉවත් කරන්න" "මේ අනුව පෙරහන්න" "අවසර අනුව පෙරහන්න" "බොහෝ අවසර" "බොහෝ ප්‍රවේශ වීම්" "මෑත" - - + "නැවුම් කරන්න" "යෙදුම් අවසර භාවිතය" "ප්‍රවේශය: වාර %1$s. මුළු කාලය: %2$s. අවසන් වරට භාවිත කළේ %3$s ඉහතය." "ප්‍රවේශය: වාර %1$s. අවසන් වරට භාවිත කළේ %2$s කට ඉහතය." @@ -137,11 +134,9 @@ "%1$s ඔබේ %2$s %3$sකට පෙර පිවිසියා." "%1$s ඔබේ %2$s වෙත පිවිස නැත." "විස්තරාත්මක අවසර භාවිතය බලන්න" - - + "අවසන් ප්‍රවේශය: %1$s" "ඉඩ දුන්" - - + "භාවිත කෙරෙන විට පමණක් අනුමත කෙරේ" "ප්‍රතික්ෂේපයි" "විස්තරාත්මක භාවිතය බලන්න" @@ -165,22 +160,6 @@ "අවසර සිහි කැඳවීම්" "%s ඔබේ ස්ථානය භාවිත කරමින් සිටියි" "මෙම යෙදුම සැමවිටම ඔබේ ස්ථානය වෙත ප්‍රවේශ විය හැක. වෙනස් කිරීමට තට්ටු කරන්න." - "යෙදුම් සංවර්ධක පවසන්නේ ඔබේ දත්ත:" - "ඔබ මෙම යෙදුම් සංවර්ධක ඔබේ දත්ත භාවිත කරන ආකාරයට අකමැති නම් ඔබට අවසරය ප්‍රතික්ෂේප කළ හැකිය." - "වැඩිදුර තොරතුරු සඳහා %s වෙත යන්න." - "වලාකුළට උඩුගත කෙරේ" - "ඔබ එයට ප්‍රකාශිතව ඉඩ දුන් විට වලාකුළට උඩුගත කෙරේ" - "වෙළඳ ප්‍රචාරකයන් හෝ ව්‍යාපාර සමග බෙදා ගැනේ" - "ඔබ එයට ප්‍රකාශිතව ඉඩ දුන් විට වෙළඳ ප්‍රචාරකයන් හෝ ව්‍යාපාර සමග බෙදා ගැනේ" - "මුදල් රැස් කිරීම සඳහා භාවිතා වේ" - "ඔබ එයට ප්‍රකාශිතව ඉඩ දුන් විට මුදල් රැස් කිරීමට භාවිත කෙරේ" - "සදහටම සුරැක විශ්ලේෂණය කෙරේ" - "ඔබ සඳහන් කරන කාල සීමාවක් සඳහා සුරැකීම සහ විශ්ලේෂණය කිරීම සිදු කෙරේ" - - සති %sක් සුරැකීම සහ විශ්ලේෂණය කිරීම සිදු කෙරේ - සති %sක් සුරැකීම සහ විශ්ලේෂණය කිරීම සිදු කෙරේ - - "යෙදුම් සංවර්ධක යෙදුම ඔබේ දත්ත භාවිත කරන ආකාරය සඳහන් කර නැත." "යෙදුම භාවිතයේ දී පමණි" "අවසරවලට ඉඩ නොදේ" "අවසර ප්‍රතික්ෂේප නොකෙරේ" @@ -205,10 +184,18 @@ "සංගීත යෙදුම" "Gallery යෙදුම" "රිය ප්‍රකාර දුරකථන යෙදුම" - "ප්‍රොක්සි කැඳවුම් යෙදුම" + + "ඇමතුම් පරීක්ෂා කිරීමේ යෙදුම" "ඇමතුම් සහායක යෙදුම" - - + "සහය යෙදුම" + "මෝටර් රථ ප්‍රක්ෂේපන යෙදුම" "සටහන: ඔබ ඔබේ උපාංගය යළි අරඹන්නේ නම් සහ තිර අඟුලක් සකසා තිබේ නම්, ඔබ ඔබේ උපාංගය අඟුලු අරින තෙක් මෙම යෙදුම ආරම්භ විය නොහැක." + "නිදොසීම් දත්ත බෙදා ගන්න" + "විස්තරාත්මක නිදොසීම් දත්ත බෙදා ගන්න ද?" + "%1$s නිදොසීම් තොරතුරු උඩුගත කිරීමට කැමතිය." + "නිදොසීම් දත්ත බෙදා ගන්න" + "%1$s මෙම උපාංගයෙන් %2$s හි %3$s හිදී ගෙන ඇති දෝෂ වාර්තාවක් උඩුගත කිරීමට ඉල්ලා සිටී. දෝෂ වාර්තාවල ඔබේ උපාංගය පිළිබඳ හෝ යෙදුම් විසින් සටහන් කර ඇති පුද්ගලික තොරතුරු, උදාහරණයක් ලෙස, පරිශීලක නාම, ස්ථාන දත්ත, උපාංග හැඳුනුම්කාරක සහ ජාල තොරතුරු ඇතුළත් වේ. ඔබ මෙම තොරතුරු සමඟ විශ්වාස කරන පුද්ගලයින් සහ යෙදුම් සමඟ පමණක් දෝෂ වාර්තා බෙදා ගන්න. %4$s හට දෝෂ වාර්තාවක් උඩුගත කිරීමට ඉඩ දෙන්න ද?" + "ඉඩ දෙන්න" + "ප්‍රතික්ෂේප කරන්න" diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml index 049337fa6..270926d16 100644 --- a/res/values-sk/strings.xml +++ b/res/values-sk/strings.xml @@ -4,9 +4,9 @@ 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. @@ -116,17 +116,14 @@ "Najviac používané povolenia za posledných 15 minút" "Najviac používané povolenia za poslednú minútu" "Aplikácie" - - - - + "Filtrované podľa: %1$s" + "Odstrániť filter" "Filtrovať podľa" "Filtrovať podľa povolení" "Najviac povolení" "Najviac prístupov" "Nedávne" - - + "Obnoviť" "Využitie povolení aplikácie" "Prístup: %1$s‑krát. Celkové trvanie: %2$s. Naposledy použité pred %3$s." "Prístup: %1$s‑krát. Naposledy použité pred %2$s." @@ -139,11 +136,9 @@ "Aplikácia %1$s použila %2$s pred %3$s." "%1$s nemôže používať povolenie %2$s." "Zobraziť podrobné údaje o využití povolení" - - + "Posledný prístup: %1$s" "Povolené" - - + "Povolené iba počas používania" "Zamietnuté" "Zobraziť podrobné údaje o využití" @@ -175,24 +170,6 @@ "Pripomenutia povolení" "%s používa vašu polohu" "Táto aplikácia má neobmedzený prístup k polohe. Klepnutím to zmeníte." - "Vývojár aplikácie tvrdí, že vaše údaje môžu byť:" - "Ak sa vám nepáči, ako tento vývojár aplikácie používa vaše údaje, môžete toto povolenie zamietnuť." - "Ďalšie informácie nájdete v aplikácii %s." - "Nahrané do cloudu" - "Nahrané do cloudu, keď to výslovne povolíte" - "Zdieľané s inzerentmi alebo firmami" - "Zdieľané s inzerentmi alebo firmami, keď to výslovne povolíte" - "Používané na speňaženie" - "Použijú sa na speňaženie, keď to výslovne povolíte" - "Uložené a analyzované navždy" - "Uložené a analyzované na obdobie, ktoré špecifikujete" - - Uložené a analyzované na %s týždne - Uložené a analyzované na %s týždňa - Uložené a analyzované na %s týždňov - Uložené a analyzované na 1 týždeň - - "Vývojár nešpecifikoval, ako jeho aplikácia používa údaje." "Iba počas používania aplikácie" "Žiadne udelené povolenia" "Žiadne odmietnuté povolenia" @@ -217,10 +194,18 @@ "Aplikácia Hudba" "Aplikácia Galéria" "Aplikácia režimu v aute pre telefóny" - "Aplikácia na volanie proxy servera" + + "Aplikácia na filtrovanie hovorov" "Sprievodná aplikácia na hovory" - - + "Asistenčná aplikácia" + "Aplikácia na projekciu v aute" "Poznámka: Ak reštartujete zariadenie a máte nastavenú zámku obrazovky, táto aplikácia sa spustí až po odomknutí zariadenia." + "Zdieľanie údajov o ladení" + "Chcete zdieľať podrobné údaje o ladení?" + "%1$s chce nahrať informácie o ladení." + "Zdieľanie údajov o ladení" + "%1$s žiada o nahranie hlásenia chyby z tohto zariadenia vytvoreného %2$s%3$s. Hlásenia chýb zahŕňajú osobné údaje o zariadení alebo osobné údaje zapísané aplikáciami, napríklad používateľské mená, údaje o polohe, identifikátory zariadenia a informácie o sieti. Hlásenia chýb zdieľajte iba s dôveryhodnými osobami a aplikáciami. Chcete povoliť aplikácii %4$s nahrať hlásenie chyby?" + "Povoliť" + "Odmietnuť" diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml index a4e7cb116..774f92346 100644 --- a/res/values-sl/strings.xml +++ b/res/values-sl/strings.xml @@ -4,9 +4,9 @@ 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. @@ -116,17 +116,14 @@ "Najvišja uporaba dovoljenj v zadnjih 15 minutah" "Najvišja uporaba dovoljenj v zadnji minuti" "Aplikacije" - - - - + "Filtrirano po: %1$s" + "Odstrani filter" "Filtriraj po" "Filtriraj po dovoljenjih" "Največ dovoljenj" "Največ dostopov" "Nedavno" - - + "Osveži" "Uporaba dovoljenj aplikacije" "Dostop: %1$s-krat. Skupno trajanje: %2$s. Nazadnje uporabljeno pred %3$s." "Dostop: %1$s-krat. Nazadnje uporabljeno pred %2$s." @@ -139,11 +136,9 @@ "Aplikacija %1$s je do dovoljenja %2$s dostopala pred %3$s." "Aplikacija %1$s ni dostopila do: %2$s." "Podroben prikaz uporabe dovoljenj" - - + "Zadnji dostop: %1$s" "Dovoljeno" - - + "Dovoljeno samo med uporabo" "Zavrnjeno" "Podroben pregled uporabe" @@ -175,24 +170,6 @@ "Opomniki za dovoljenja" "Aplikacija %s je uporabljala vašo lokacijo" "Ta aplikacija lahko vedno dostopa do vaše lokacije. Dotaknite se, če želite spremeniti dovoljenje." - "Razvijalec aplikacije navaja, da so vaši podatki lahko:" - "Če vam ni všeč, kako razvijalec te aplikacije uporablja vaše podatke, lahko dovoljenje zavrnete." - "Več informacij najdete v aplikaciji %s." - "Naloženi v oblak" - "Naloženi v oblak, ko to izrecno dovolite" - "Posredovani oglaševalcem ali podjetjem" - "Posredovani oglaševalcem ali podjetjem, ko to izrecno dovolite" - "Uporabljeni za ovrednotenje" - "Uporabljeni za ovrednotenje, ko to izrecno dovolite" - "Shranjeni in analizirani za vedno" - "Shranjeni in analizirani za obdobje, ki ga določite" - - Shranjeni in analizirani %s teden - Shranjeni in analizirani %s tedna - Shranjeni in analizirani %s tedne - Shranjeni in analizirani %s tednov - - "Razvijalec aplikacije ni določil, kako aplikacija uporablja vaše podatke." "Samo, ko je aplikacija v uporabi" "Aplikacija nima nobenih dovoljenj" "Nobeno dovoljenje ni odvzeto" @@ -217,10 +194,18 @@ "Aplikacija Glasba" "Aplikacija Galerija" "Apl. Telefon v načinu za avto." - "Apl. za klice prek posrednika" + + "Aplikacija za pregled klicev" "Spremljevalna apl. za klicanje" - - + "Aplikacija za pomoč" + "Apl. za projiciranje v avtu" "Opomba: Po vnovičnem zagonu naprave z nastavljenim zaklepanjem zaslona se ta aplikacija ne more zagnati, dokler ne odklenete naprave." + "Pošiljanje podatkov za odpravljanje napak" + "Želite poslati podrobne podatke za odprav. napak?" + "Aplikacija %1$s želi naložiti podatke za odpravljanje napak." + "Pošiljanje podatkov za odpravljanje napak" + "Aplikacija %1$s želi iz te naprave naložiti poročilo o napakah, pripravljeno dne %2$s ob %3$s. Poročila o napakah vključujejo osebne podatke o vaši napravi ali osebne podatke, ki so jih zabeležile aplikacije, na primer uporabniška imena, lokacijske podatke, identifikatorje naprave in podatke o omrežju. Poročila o napakah delite samo z osebami in aplikacijami, ki jim te podatke lahko zaupate. Ali aplikaciji %4$s dovolite, da naloži poročilo o napakah?" + "Dovoli" + "Zavrni" diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml index 5ff6cba81..6f9b1a545 100644 --- a/res/values-sq/strings.xml +++ b/res/values-sq/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "Përdorimet kryesore të autorizimeve në 15 minutat e fundit" "Përdorimet kryesore të autorizimeve në minutën e fundit" "Aplikacionet" - - - - + "Filtruar sipas: %1$s" + "Hiq filtrin" "Filtro sipas" "Filtro sipas autorizimeve" "Shumica e autorizimeve" "Shumica e qasjeve" "Më të fundit" - - + "Rifresko" "Përdorimi i lejeve të apl." "Qasja: %1$s herë. Kohëzgjatja gjithsej: %2$s. Përdorur së fundi %3$s më parë." "Qasja: %1$s herë. Përdorur së fundi %2$s më parë." @@ -137,11 +134,9 @@ "%1$s pati qasje te %2$s %3$s më parë." "%1$s nuk ka pasur qasje te %2$s." "Shiko përdorimin e detajuar të autorizimeve" - - + "Qasja e fundit: %1$s" "Të lejuara" - - + "Lejohet vetëm kur është në përdorim" "Të refuzuara" "Shiko përdorimin e detajuar" @@ -165,22 +160,6 @@ "Alarmet rikujtuese për lejet" "%s ka përdorur vendndodhjen tënde" "Ky aplikacion mund të qaset gjithmonë te vendndodhja jote. Trokit për ta ndryshuar." - "Zhvilluesi i aplikacionit thotë se të dhënat e tua mund:" - "Nëse nuk të pëlqen se si po i përdor të dhënat e tua ky zhvillues aplikacioni, mund ta refuzosh lejen." - "Shko te %s për informacione të tjera." - "Të ngarkohen në renë kompjuterike" - "Të ngarkohen në renë kompjuterike kur lejohet qartësisht nga ty" - "Të ndahen me reklamuesit ose bizneset" - "Të ndahen me reklamuesit ose bizneset kur lejohet qartësisht nga ty" - "Të përdoren për fitim parash" - "Të përdoren për fitimin e parave kur lejohet qartësisht nga ty" - "Të ruhen dhe të analizohen përgjithmonë" - "Të ruhen dhe të analizohen për kohëzgjatjen e specifikuar nga ty" - - Të ruhen dhe të analizohen për %s javë - Të ruhen dhe të analizohen për 1 javë - - "Zhvilluesi i aplikacionit nuk ka specifikuar se si i përdor aplikacioni të dhënat e tua." "Vetëm kur aplikacioni është në përdorim" "Nuk jepet asnjë leje" "Asnjë leje nuk është refuzuar" @@ -205,10 +184,18 @@ "Aplikacioni i muzikës" "Aplikacioni i galerisë" "Apl. i modalitetit \"në makinë\"" - "Apl. i telefonimit me përfaqësues" + + "Apl. i filtrimit të telefonatave" "Apl. shoqërues i telefonatave" - - + "Aplikacioni i asistentit" + "Aplikacioni i \"Projektimit të makinës\"" "Shënim: Nëse e rinis pajisjen dhe ke caktuar një kyçje të ekranit, ky aplikacion nuk mund të niset derisa ta shkyçësh pajisjen." + "Ndaj të dhënat e korrigjimit" + "Të ndahen të dhënat e detajuara të korrigjimit?" + "%1$s dëshiron të ngarkojë informacionin e korrigjimit." + "Ndaj të dhënat e korrigjimit" + "%1$s kërkon të ngarkojë një raport të defekteve në kod nga kjo pajisje të regjistruar më %2$s%3$s. Raportet e defekteve në kod përfshijnë informacione personale rreth pajisjes sate ose të regjistruara nga aplikacionet, për shembull emrat e përdoruesve, të dhënat e vendndodhjes, identifikuesit e pajisjeve, si dhe informacione të rrjetit. Ndaji raportet e defekteve në kod vetëm me personat dhe aplikacionet që i beson me këtë informacion. Të lejohet %4$s të ngarkojë një raport të defekteve në kod?" + "Lejo" + "Refuzo" diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml index c4c8b094d..2c89bfbe2 100644 --- a/res/values-sr/strings.xml +++ b/res/values-sr/strings.xml @@ -4,9 +4,9 @@ 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. @@ -115,17 +115,14 @@ "Највише коришћене дозволе у последњих 24 минута" "Највише коришћене дозволе у последњем минуту" "Апликације" - - - - + "Филтрирано према: %1$s" + "Уклони филтер" "Филтрирај према" "Филтрирај према дозволама" "Највише дозвола" "Највећи број приступа" "Недавно" - - + "Освежи" "Коришћење дозвола за аплик." "Приступ: %1$s пут(а). Укупно трајање: %2$s. Последњи пут коришћена пре %3$s." "Приступ: %1$s пут(а). Последњи пут коришћена пре %2$s." @@ -138,11 +135,9 @@ "Апликација %1$s је приступила дозволи %2$s пре %3$s." "Апликација %1$s није приступила дозволи %2$s." "Прегледајте детаљне дозволе за коришћење" - - + "Последњи приступ: %1$s" "Дозвољено" - - + "Дозвољено само док се апликација користи" "Одбијено" "Погледајте детаљну употребу" @@ -170,23 +165,6 @@ "Подсетници за дозволе" "%s користи вашу локацију" "Ова апликација може увек да приступа локацији. Додирните да бисте то променили." - "Програмер апликације каже да подаци могу:" - "Ако вам се не свиђа како овај програмер апликације користи податке, можете да повучете дозволу." - "Идите у апликацију %s да бисте добили више информација." - "да се отпремају у клауд" - "да се отпремају у клауд када то изричито дозволите" - "да се деле са оглашавачима или предузећима" - "да се деле са оглашавачима или предузећима када то изричито дозволите" - "да се користе за монетизацију" - "да се користе за монетизацију када то изричито дозволите" - "да се чувају и анализирају заувек" - "да се чувају и анализирају у периоду који ви наведете" - - да се чувају и анализирају %s недељу - да се чувају и анализирају %s недеље - да се чувају и анализирају %s недеља - - "Програмер апликације није навео како апликација користи податке." "Само док се апликација користи" "Дозволе нису одобрене" "Ниједна дозвола није одбијена" @@ -211,10 +189,18 @@ "Апликација Музика" "Апликација Галерија" "Апликација за телефон са режимом рада у аутомобилу" - "Апликација за прокси позиве" + + "Аплик. за управ. долаз. позив." "Позивање пратеће апликације" - - + "Апликација за помоћ" + "Аплик. Пројекција у аутомобилу" "Напомена: Ако рестартујете уређај и подесили сте закључавање екрана, ова апликација не може да се покрене док не откључате уређај." + "Дељење података о отклањању грешака" + "Делите детаљне податке за отклањање грешака?" + "%1$s жели да отпреми информације за отклањање грешака." + "Дељење података о отклањању грешака" + "%1$s тражи да отпреми извештај о грешкама са овог уређаја који је направљен %2$s у %3$s. Извештаји о грешкама обухватају личне податке о уређају или податке које су евидентирале апликације, на пример, корисничка имена, податке о локацији, идентификаторе уређаја и информације о мрежи. Делите извештаје о грешкама само са људима и апликацијама којима можете да поверите те информације. Желите ли да дозволите да %4$s отпреми извештај о грешци?" + "Дозволи" + "Одбиј" diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml index 116327713..c2f7ffd32 100644 --- a/res/values-sv/strings.xml +++ b/res/values-sv/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "Vanlig behörighetsanvändning de senaste 15 min" "Vanlig behörighetsanvändning den senaste minuten" "Appar" - - - - + "Filtreras efter: %1$s" + "Ta bort filter" "Filtrera efter" "Filtrera efter behörigheter" "Flest behörigheter" "Flest åtkomster" "Senaste" - - + "Uppdatera" "Appens behörighetsanvändning" "Åtkomst: %1$s gånger. Användningstid totalt: %2$s. Användes senast för %3$s sedan." "Åtkomst: %1$s gånger. Användes senast för %2$s sedan." @@ -137,11 +134,9 @@ "%1$s använde din %2$s för %3$s sedan." "%1$s har inte fått åtkomst till %2$s." "Visa utförlig information om behörighetsanvändning" - - + "Användes senast: %1$s" "Tillåts" - - + "Tillåt bara vid användning" "Nekas" "Visa utförlig information om användning" @@ -165,22 +160,6 @@ "Behörighetspåminnelser" "%s har använt din plats" "Den här appen har alltid åtkomst till din plats. Tryck här om du vill ändra det." - "Enligt apputvecklaren kan din data" - "Om du inte gillar hur apputvecklaren använder din data kan du neka behörighet." - "Du hittar mer information i %s" - "laddas upp på molet" - "laddas upp på molnen när du tillåter det" - "delas med annonsörer eller företag" - "delas med annonsörer och företag när du tillåter det" - "användas till vinstgenerering" - "användas till vinstgenerering när du tillåter det" - "sparas och analyseras för alltid" - "sparas och analyseras under en tidsperiod som du anger" - - sparas och analyseras i %s veckor - sparas och analyseras i en vecka - - "Apputvecklaren har inte angett hur appen använder din data." "Endast när appen används" "Inga behörigheter har beviljats" "Inga behörigheter har nekats" @@ -205,10 +184,18 @@ "Appen Musik" "Appen Galleri" "Mobilapp för billäge" - "App för omdirigering av samtal" + + "App för samtalsspärr" "Tillhörande samtalsapp" - - + "Assistentapp" + "App för projicering i bilen" "Obs! Om du startar om mobilen och har ställt in ett skärmlås kan appen inte startas förrän du låser upp mobilen." + "Dela felsökningsinformation" + "Vill du dela detaljerad felsökningsinformation?" + "%1$s vill ladda upp felsökningsinformation." + "Dela felsökningsinformation" + "%1$s begär tillstånd att ladda upp en felrapport som sparades den %2$s kl. %3$s från den här enheten. Felrapporter innehåller personlig information om enheten eller information som loggats av appar, t.ex. användarnamn, platsdata, enhetsidentifierare och nätverksinformation. Dela bara felrapporter med personer och appar du litar på. Tillåter du att %4$s laddar upp en felrapport?" + "Tillåt" + "Neka" diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml index 5ef29f290..730cdf4b4 100644 --- a/res/values-sw/strings.xml +++ b/res/values-sw/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "Ruhusa zilizotumiwa zaidi dakika 15 zilizopita" "Ruhusa zilizotumiwa zaidi dakika 1 iliyopita" "Programu" - - - - + "Zilizochujwa kulingana na: %1$s" + "Ondoa kichujio" "Chuja kulingana na" "Chuja kulingana na ruhusa" "Ruhusa nyingi zaidi" "Zilizotumiwa zaidi" "Za hivi majuzi" - - + "Onyesha upya" "Matumizi ya idhini za programu" "Ufikiaji: mara %1$s. Jumla ya muda: %2$s. Mara ya mwisho ilitumika %3$s zilizopita." "Ufikiaji: mara %1$s. Mara ya mwisho ilitumika %2$s zilizopita." @@ -137,11 +134,9 @@ "%1$s imefikia %2$s yako %3$s zilizopita." "%1$s haijafikia %2$s yako." "Angalia matumizi ya ruhusa za kina" - - + "Imetumiwa mwisho: %1$s" "Zinazoruhusiwa" - - + "Inaruhusiwa tu wakati inatumika" "Imekataliwa" "Ona matumizi ya kina" @@ -165,22 +160,6 @@ "Vikumbusho vya ruhusa" "%s imekuwa ikitumia maelezo ya mahali ulipo" "Programu hii inaweza kufikia maelezo ya mahali ulipo kila wakati. Gusa ili ubadilishe." - "Msanidi wa programu anasema kuwa huenda data yako:" - "Kama hupendi jinsi msanidi wa programu anavyotumia data yako unaweza kukataa kumpa ruhusa." - "Fungua %s ili upate maelezo zaidi" - "Itapakiwa kwenye wingu" - "Itapakiwa kwenye wingu unapotoa ruhusa bayana" - "Itashirikiwa na watangazaji au biashara" - "Itashirikiwa na watangazaji au biashara unapotoa ruhusa bayana" - "Inatumika katika uchumaji wa mapato" - "Itatumika katika uchumaji wa mapato unapotoa ruhusa bayana" - "Itahifadhiwa na kuchambuliwa milele" - "Itahifadhiwa na kuchambuliwa kwa kipindi utakachobainisha" - - Itahifadhiwa na kuchambuliwa kwa wiki %s - Itahifadhiwa na kuchambuliwa kwa wiki 1 - - "Msanidi wa programu hakubainisha jinsi programu inavyotumia data yako." "Wakati programu inatumika pekee" "Hakuna ruhusa zilizotolewa" "Hakuna ruhusa ambazo hazijatolewa" @@ -205,10 +184,18 @@ "Programu ya muziki" "Programu ya matunzio" "Programu ya simu katika hali ya gari" - "Programu ya kupiga simu kupitia seva mbadala" + + "Programu ya kuchuja simu" "Programu ya kusaidia kupiga simu" - - + "Programu ya mratibu" + "Programu ya Kuakisi Simu Garini" "Kumbuka: Kama utazima kisha uwashe kifaa chako na uwe umeweka njia ya kufunga skrini, programu hii haitafanya kazi hadi ufungue kifaa chako." + "Shiriki Data ya Utatuzi" + "Ungependa kushiriki data ya kina ya utatuzi?" + "%1$s inataka kupakia maelezo ya utatuzi." + "Shiriki Data ya Utatuzi" + "%1$s inaomba kupakua ripoti ya hitilafu kutoka kifaa hiki, iliyochakatwa tarehe %2$s saa %3$s. Ripoti za hitilafu hujumuisha taarifa binafsi kuhusu kifaa chako au iliyohifadhiwa na programu, kwa mfano, majina ya watumiaji, data ya mahali, vitambulishi vya vifaa na maelezo ya mtandao. Shiriki tu ripoti za hitilafu na watu au programu unazoamini kupokea maelezo haya. Ungependa kuruhusu %4$s ipakie ripoti ya hitilafu?" + "Ruhusu" + "Kataa" diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml index 8e0ac7283..e6b75297c 100644 --- a/res/values-ta/strings.xml +++ b/res/values-ta/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "கடந்த 15 நிமிடத்தில் உபயோகித்த அதிகபட்ச அனுமதி" "கடந்த 1 நிமிடத்தில் உபயோகித்த அதிகபட்ச அனுமதி" "ஆப்ஸ்" - - - - + "இதன்படி வடிகட்டப்பட்டது: %1$s" + "வடிப்பானை அகற்று" "இதன்படி வடிகட்டுதல்" "அனுமதிகளின்படி வடிகட்டு" "அதிகப்படியான அனுமதிகள்" "அதிகப்படியான அணுகல்கள்" "சமீபத்தியவை" - - + "புதுப்பி" "ஆப்ஸ் அனுமதிகளை உபயோகித்தல்" "அணுகல்: %1$s முறை. மொத்தக் கால அளவு: %2$s. கடைசியாகப் பயன்படுத்தியது %3$s முன்பு." "அணுகல்: %1$s முறை. கடைசியாகப் பயன்படுத்தியது %2$s முன்பு." @@ -137,11 +134,9 @@ "%3$s நேரத்திற்கு முன்பு %1$s ஆப்ஸ் உங்கள் %2$sஐ அணுகியது." "%1$s உங்கள் %2$s அனுமதியைப் பயன்படுத்தவில்லை." "அனுமதிகளின் உபயோகம் தொடர்பான விவரங்களைக் காட்டு" - - + "கடைசியாகப் பயன்படுத்தியது: %1$s" "அனுமதிக்கப்பட்டவை" - - + "உபயோகத்தில் மட்டுமே அனுமதிக்கப்படும்" "மறுக்கப்பட்டது" "உபயோகத்தை விவரமாகக் காட்டு" @@ -165,22 +160,6 @@ "அனுமதிக்கான நினைவூட்டல்கள்" "%s உங்கள் இருப்பிடத்தைப் பயன்படுத்துகிறது" "எப்பொழுதும் உங்கள் இருப்பிடத்தை இந்த ஆப்ஸால் பயன்படுத்த இயலும். மாற்றத் தட்டவும்." - "உங்கள் தரவிற்குப் பின்வருமாறு நேரலாம் என ஆப்ஸ் டெவெலப்பர் தெரிவிக்கிறார்:" - "தரவை ஆப்ஸ் டெவெலப்பர் பயன்படுத்தும் விதம் குறித்துத் தெரியவில்லை எனில் அனுமதியை நீங்கள் நிராகரிக்கலாம்." - "மேலும் தகவலுக்கு %s ஆப்ஸிற்குச் செல்லவும்." - "கிளவுடில் பதிவேற்றப்படும்" - "நீங்கள் வெளிப்படையாக அனுமதிக்கும்போது கிளவுடில் பதிவேற்றப்படும்" - "விளம்பரதாரர்களுடனோ வணிகங்களுடனோ பகிரப்படும்" - "நீங்கள் வெளிப்படையாக அனுமதிக்கும்போது விளம்பரதாரர்களுடனோ வணிகங்களுடனோ பகிரப்படும்" - "லாபம் பெறுவதற்குப் பயன்படுத்தப்படும்" - "நீங்கள் வெளிப்படையாக அனுமதிக்கும்போது லாபம் பெறுவதற்குப் பயன்படுத்தப்படும்" - "தரவு சேமிக்கப்பட்டு எப்போதும் பகுப்பாய்வு செய்யப்படும்" - "சேமிக்கப்பட்டு நீங்கள் குறிப்பிடும் காலத்திற்குப் பகுப்பாய்வு செய்யப்படும்" - - சேமிக்கப்பட்டு %s வாரங்களுக்குப் பகுப்பாய்வு செய்யப்படும் - சேமிக்கப்பட்டு 1 வாரத்திற்குப் பகுப்பாய்வு செய்யப்படும் - - "ஆப்ஸ் உங்கள் தரவை எவ்வாறு பயன்படுத்துகிறது என ஆப்ஸ் டெவெலப்பர் குறிப்பிடவில்லை." "ஆப்ஸ் உபயோகத்தில் இருக்கும்போது மட்டும்" "எந்த அனுமதிகளும் வழங்கப்படவில்லை" "எந்த அனுமதிகளும் மறுக்கப்படவில்லை" @@ -205,10 +184,18 @@ "மியூசிக் ஆப்ஸ்" "கேலரி ஆப்ஸ்" "கார் மோடுக்கான மொபைல் ஆப்ஸ்" - "ப்ராக்ஸி அழைப்பு ஆப்ஸ்" + + "அழைப்புத் திரை ஆப்ஸ்" "அழைப்புக்கான கம்பேனியன் ஆப்ஸ்" - - + "அசிஸ்ட் ஆப்ஸ்" + "கார் காட்சிப்படுத்தல் ஆப்ஸ்" "கவனத்திற்கு: திரைப் பூட்டு அமைக்கப்பட்டிருக்கும் நிலையில் உங்கள் மொபைலை மீண்டும் தொடங்கினால் அன்லாக் செய்யப்படும்வரை இந்த ஆப்ஸ் இயங்காது." + "பிழைதிருத்தத் தரவைப் பகிர்தல்" + "விரிவான பிழைதிருத்தத் தகவலைப் பகிரவா?" + "பிழைதிருத்தத் தகவலை %1$s பதிவேற்ற விரும்புகிறது." + "பிழைதிருத்தத் தரவைப் பகிர்தல்" + "இந்தச் சாதனத்திலிருந்து %2$s அன்று %3$s மணிக்கு எடுக்கப்பட்ட பிழை அறிக்கையைப் பதிவேற்றுமாறு %1$s கோருகிறது. இதில் பயனர் பெயர்கள், இருப்பிடத் தரவு, சாதன அடையாளங்காட்டிகள் மற்றும் நெட்வொர்க் தகவல்கள் போன்ற உங்கள் சாதனம் அல்லது உள்நுழைந்துள்ள ஆப்ஸ் பற்றிய தனிப்பட்ட தகவல்களும் உள்ளடங்கும். இந்தத் தகவல்களுடனான பிழை அறிக்கைகளை நம்பகமானவர்களுடனும் ஆப்ஸுடனும் மட்டுமே பகிரவும். பிழை அறிக்கையைப் பதிவேற்ற %4$s ஆப்ஸை அனுமதிக்கவா?" + "அனுமதி" + "நிராகரி" diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml index 4f4ebaea9..36aa4a057 100644 --- a/res/values-te/strings.xml +++ b/res/values-te/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "గత 15 నిమిషాల్లో అగ్రశ్రేణి అనుమతి వినియోగం" "గత నిమిషంలో అగ్రశ్రేణి అనుమతి వినియోగం" "యాప్‌లు" - - - - + "దీని ద్వారా ఫిల్టర్ చేయబడింది: %1$s" + "ఫిల్టర్‌ తీసివేయి" "వీటి ద్వారా ఫిల్టర్ చేయి" "అనుమతుల ఆధారంగా ఫిల్టర్ చేయండి" "దాదాపుగా అన్ని అనుమతులు" "మరిన్ని యాక్సెస్‌లు" "ఇటీవలివి" - - + "రిఫ్రెష్ చేయి" "యాప్ అనుమతుల వినియోగం" "యాక్సెస్: %1$s సార్లు. మొత్తం వ్యవధి: %2$s. %3$s క్రితం చివరిగా ఉపయోగించబడింది." "యాక్సెస్: %1$s సార్లు. %2$s క్రితం చివరిగా ఉపయోగించబడింది." @@ -137,11 +134,9 @@ "%1$s మీ %2$sని %3$s క్రితం యాక్సెస్ చేసింది." "%1$s మీ %2$sని ఉపయోగించలేదు." "వివరణాత్మక అనుమతుల వినియోగాన్ని చూడండి" - - + "చివరిసారి యాక్సెస్ చేసింది: %1$s" "అనుమతించినవి" - - + "ఉపయోగించేటప్పుడు మాత్రమే అనుమతివ్వబడును" "తిరస్కరించినవి" "వివరణాత్మక వినియోగాన్ని చూడండి" @@ -165,22 +160,6 @@ "అనుమతి రిమైండర్‌లు" "%s మీ స్థానాన్ని ఉపయోగిస్తోంది" "ఈ యాప్ మీ స్థానాన్ని ఎల్లప్పుడూ యాక్సెస్ చేయగలదు. మార్చడానికి నొక్కండి." - "మీ డేటా ఏవిధంగా ఉపయోగించబడవచ్చు అనేది యాప్ డెవలపర్ చెప్తున్నారు:" - "ఈ యాప్ డెవలపర్ మీ డేటాని ఉపయోగించుకునే పద్ధతి మీకు నచ్చకపోతే నిశ్చింతగా అనుమతిని తిరస్కరించవచ్చు." - "మరింత సమాచారం కోసం %sకు వెళ్లండి." - "క్లౌడ్‌లోకి అప్‌లోడ్ చేయబడుతుంది" - "మీరు స్పష్టంగా అనుమతించినప్పుడు, క్లౌడ్‌లోకి అప్‌లోడ్ చేయబడుతుంది" - "ప్రకటనదారులతో లేదా వ్యాపారాలతో షేర్ చేయబడుతుంది" - "మీరు స్పష్టంగా అనుమతించినప్పుడు, ప్రకటనదారులతో లేదా వ్యాపారాలతో షేర్ చేయబడుతుంది" - "డబ్బు ఆర్జన కోసం ఉపయోగించబడుతుంది" - "మీరు స్పష్టంగా అనుమతించినప్పుడు, డబ్బు ఆర్జన కోసం ఉపయోగించబడుతుంది" - "ఎల్లప్పుడూ సేవ్ చేసి, విశ్లేషిస్తుంది" - "మీరు నిర్దేశించిన సమయం వరకు సేవ్ చేసి, విశ్లేషిస్తుంది" - - %s వారాలలో సేవ్ చేసి, విశ్లేషించినది - 1 వారంలో సేవ్ చేసి, విశ్లేషించినది - - "యాప్ మీ డేటాని ఏవిధంగా ఉపయోగించుకుంటుంది అనేది యాప్ డెవలపర్‌ పేర్కొన‌లేదు." "యాప్ వినియోగంలో ఉన్నప్పుడు మాత్రమే" "అనుమతులు ఏవీ ఇవ్వలేదు" "అన్ని అనుమతులు ఇచ్చారు" @@ -205,10 +184,18 @@ "సంగీత యాప్" "గ్యాలరీ యాప్‌" "కార్ మోడ్ ఫోన్ యాప్" - "ప్రాక్సీ కాలింగ్ యాప్" + + "కాల్ స్క్రీనింగ్ యాప్" "కాల్ సహచర యాప్" - - + "సహాయక యాప్" + "కార్ ప్రొజెక్షన్ యాప్" "చిన్న గమనిక: మీరు భద్రత కోసం స్క్రీన్ లాక్‌ని సెటప్‌ చేసి పెట్టుకున్నారు పైగా మీ పరికరాన్ని పునఃప్రారంభించినట్టున్నారు కనుక స్క్రీన్ లాక్ అయ్యిపోయింది. మీరు పాస్‌వర్డ్‌ని నమోదు చేసేవరకూ ఈ యాప్ ప్రారంభం కాదు." + "డీబగ్గింగ్ డేటాను షేర్ చేయండి" + "వివరణాత్మక డీబగ్గింగ్ డేటాను షేర్ చేయాలా?" + "%1$sడీబగ్గింగ్ సమాచారాన్ని అప్‌లో డ్ చేయదలుచుకుంటున్నారు." + "డీబగ్గింగ్ డేటాను షేర్ చేయండి" + "%1$s %2$s%3$sకు ఈ పరికరంలో తీసిన డీబగ్ నివేదికను అప్‌లోడ్ చేయమని అభ్యర్థిస్తుంది. బగ్ నివేదికలు మీ పరికరం లేదా లాగిన్ చేసిన యాప్‌ల వ్యక్తిగత సమాచారం, ఉదాహరణకు వినియోగదారు పేర్లు, స్థాన డేటా, పరికర గుర్తింపులు,మరియి నెట్‌వర్క్ సమాచారాన్ని కలిగి ఉంటాయి. మీకు ఈ సమాచారం విషయంలో నమ్మకమైన వ్యక్తులకు మరియు యాప్‌లకు మాత్రమే బగ్ నివేదిక వివరాలను షేర్ చేయండి. బగ్ నివేదికను అప్‌లోడ్ చేయడానికి %4$sను అనుమతించాలా?" + "అనుమతించు" + "తిరస్కరించు" diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml index 13c90cf20..014f180ee 100644 --- a/res/values-th/strings.xml +++ b/res/values-th/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "การใช้สิทธิ์สูงสุดในช่วง 15 นาทีที่ผ่านมา" "การใช้สิทธิ์สูงสุดในช่วง 1 นาทีที่ผ่านมา" "แอป" - - - - + "กรองตาม: %1$s" + "นำตัวกรองออก" "กรองตาม" "กรองตามสิทธิ์" "สิทธิ์ที่ใช้มากที่สุด" "การเข้าถึงมากที่สุด" "ล่าสุด" - - + "รีเฟรช" "การใช้สิทธิ์ของแอป" "เข้าถึง: %1$s ครั้ง ระยะเวลารวม: %2$s ใช้ล่าสุดเมื่อ %3$sที่ผ่านมา" "เข้าถึง: %1$s ครั้ง ใช้ล่าสุดเมื่อ %2$sที่ผ่านมา" @@ -137,11 +134,9 @@ "%1$s เข้าถึง%2$sของคุณเมื่อ %3$s ที่ผ่านมา" "%1$s ไม่ได้เข้าถึง %2$s ของคุณ" "ดูรายละเอียดการใช้สิทธิ์" - - + "เข้าถึงล่าสุด: %1$s" "ได้รับอนุญาตแล้ว" - - + "อนุญาตขณะใช้งานอยู่เท่านั้น" "ถูกปฏิเสธ" "ดูการใช้งานโดยละเอียด" @@ -165,22 +160,6 @@ "การช่วยเตือนเกี่ยวกับสิทธิ์" "%s ใช้ตำแหน่งของคุณ" "แอปนี้เข้าถึงตำแหน่งของคุณได้ตลอดเวลา แตะเพื่อเปลี่ยน" - "นักพัฒนาแอประบุว่าอาจมีการนำข้อมูลของคุณมาใช้ดังนี้" - "หากไม่ชอบวิธีที่นักพัฒนาแอปรายนี้ใช้ข้อมูลของคุณ คุณปฏิเสธสิทธิ์ได้" - "ดูข้อมูลเพิ่มเติมได้ใน %s" - "อัปโหลดไปยังระบบคลาวด์" - "อัปโหลดไปยังระบบคลาวด์ในกรณีที่คุณอนุญาตอย่างชัดเจน" - "แชร์กับผู้ลงโฆษณาหรือธุรกิจ" - "แชร์กับผู้ลงโฆษณาหรือธุรกิจในกรณีที่คุณอนุญาตอย่างชัดเจน" - "ใช้สำหรับการสร้างรายได้" - "ใช้สำหรับการสร้างรายได้ในกรณีที่คุณอนุญาตอย่างชัดเจน" - "บันทึกไว้และใช้วิเคราะห์ถาวร" - "บันทึกไว้และใช้วิเคราะห์ตามระยะเวลาที่คุณระบุ" - - บันทึกไว้และใช้วิเคราะห์เป็นเวลา %s สัปดาห์ - บันทึกไว้และใช้วิเคราะห์เป็นเวลา 1 สัปดาห์ - - "นักพัฒนาแอปไม่ได้ระบุว่าแอปจะใช้ข้อมูลของคุณอย่างไร" "เมื่อมีการใช้แอปเท่านั้น" "ไม่ได้ให้สิทธิ์ใดเลย" "ไม่ได้ปฏิเสธสิทธิ์ใดเลย" @@ -205,10 +184,18 @@ "แอปเพลง" "แอปแกลเลอรี" "แอปโทรศัพท์ในโหมดรถยนต์" - "แอปการโทรพร็อกซี" + + "แอปสกรีนสายเรียกเข้า" "แอปที่ใช้ร่วมกับการโทร" - - + "แอปผู้ช่วย" + "แอป Car Projection" "หมายเหตุ: หากคุณรีสตาร์ทอุปกรณ์และตั้งการล็อกหน้าจอไว้ แอปนี้จะเริ่มทำงานไม่ได้จนกว่าคุณจะปลดล็อกอุปกรณ์" + "แชร์ข้อมูลการแก้ไขข้อบกพร่อง" + "แชร์ร์ข้อมูลการแก้ไขข้อบกพร่องโดยละเอียดไหม" + "%1$s ต้องการอัปโหลดข้อมูลการแก้ไขข้อบกพร่อง" + "แชร์ข้อมูลการแก้ไขข้อบกพร่อง" + "%1$s กำลังขออัปโหลดรายงานข้อบกพร่องจากอุปกรณ์นี้ซึ่งบันทึกไว้เมื่อวันที่ %2$s เวลา %3$s รายงานข้อบกพร่องมีข้อมูลส่วนบุคคลเกี่ยวกับอุปกรณ์ของคุณหรือที่แอปต่างๆ บันทึกไว้ เช่น ชื่อผู้ใช้ ข้อมูลตำแหน่ง ตัวระบุอุปกรณ์ และข้อมูลเครือข่าย โปรดแชร์รายงานข้อบกพร่องกับบุคคลและแอปที่คุณไว้วางใจให้เห็นข้อมูลนี้เท่านั้น อนุญาตให้ %4$s อัปโหลดรายงานข้อบกพร่องไหม" + "อนุญาต" + "ปฏิเสธ" diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml index dc6b4bfa6..3b4bf6e40 100644 --- a/res/values-tl/strings.xml +++ b/res/values-tl/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "Pinakamadalas gamiting pahintulot sa huling 15 min" "Pinakamadalas gamiting pahintulot sa huling 1 oras" "Mga App" - - - - + "Na-filter ng: %1$s" + "Alisin ang filter" "I-filter ayon sa" "I-filter ayon sa mga pahintulot" "Pinakamaraming pahintulot" "Pinakamaraming pag-access" "Kamakailan Lang" - - + "I-refresh" "Paggamit ng pahintulot sa app" "Na-access nang: %1$s (na) beses. Kabuuang tagal: %2$s. Huling ginamit %3$s ang nakalipas." "Na-access nang: %1$s (na) beses. Huling ginamit %2$s ang nakalipas." @@ -137,11 +134,9 @@ "Na-access ng %1$s ang iyong %2$s %3$s ang nakalipas." "Hindi na-access ng %1$s ang iyong %2$s." "Tingnan ang detalyadong paggamit sa mga pahintulot" - - + "Huling na-access: %1$s" "Pinapayagan" - - + "Pinapayagan lang habang ginagamit" "Tinanggihan" "Tingnan ang detalyadong paggamit" @@ -165,22 +160,6 @@ "Mga paalala sa pahintulot" "Ginagamit ng %s ang iyong lokasyon" "Maa-access ng app na ito ang iyong lokasyon anumang oras. I-tap para baguhin." - "Ayon sa developer ng app, ang iyong data ay maaaring:" - "Kung hindi mo gusto kung paano ginagamit ng developer ng app na ito ang iyong data, maaari mong tanggihan ang pahintulot." - "Pumunta sa %s para sa higit pang impormasyon." - "I-upload sa cloud" - "I-upload sa cloud kapag tahasan mo itong pinayagan" - "Ibahagi sa mga advertiser o negosyo" - "Ibahagi sa mga advertiser o negosyo kapag tahasan mo itong pinayagan" - "Gamitin para sa monetization" - "Gamitin para sa monetization kapag tahasan mo itong pinayagan" - "I-save at suriin habambuhay" - "I-save at suriin sa loob ng tagal ng panahong tutukuyin mo" - - I-save at suriin sa loob ng %s (na) linggo - I-save at suriin sa loob ng %s (na) linggo - - "Hindi tinukoy ng developer ng app kung paano gagamitin ng app ang iyong data." "Habang ginagamit lang ang app" "Walang pinayagang pahintulot" "Walang tinanggihang pahintulot" @@ -205,10 +184,18 @@ "Music app" "Gallery app" "App na telepono ng car mode" - "Proxy na app sa pagtawag" + + "App ng pag-screen ng tawag" "Kasamang app sa pagtawag" - - + "Assist app" + "Car Projection app" "Tandaan: Kung ire-restart mo ang iyong device at may nakatakdang lock ng screen, hindi makakapagsimula ang app na ito hanggang sa i-unlock mo ang iyong device." + "Ibahagi ang Data sa Pag-debug" + "Ibahagi ang nakadetalyeng data sa pag-debug?" + "Gustong mag-upload ng %1$s ng impormasyon sa pag-debug." + "Ibahagi ang Data sa Pag-debug" + "Hinihiling ng %1$s na mag-upload ng ulat ng bug mula sa device na ito na kinuha noong %2$s sa ganap na %3$s. Kabilang sa mga ulat ng bug ang personal na impormasyon tungkol sa iyong device o naka-log ayon sa mga app, halimbawa, mga user name, data ng lokasyon, pagkakakilanlan ng device, at impormasyon ng network. Magbahagi lang ng mga ulat ng bug sa mga tao at app na pinagkakatiwalaan mo ng impormasyong ito. Payagan ang %4$s na mag-upload ng ulat ng bug?" + "Payagan" + "Tanggihan" diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml index a178e41da..4903d30c8 100644 --- a/res/values-tr/strings.xml +++ b/res/values-tr/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "Son 15 dakika içinde en çok kullanılan izinler" "Son 1 dakika içinde en çok kullanılan izinler" "Uygulamalar" - - - - + "Filtre ölçütü: %1$s" + "Filtreyi kaldır" "Filtre uygulama ölçütü" "İzinlere göre filtrele" "En çok kullanılan izinler" "En yüksek erişim" "Son erişilenler" - - + "Yenile" "Uygulama izinleri kullanımı" "Erişim: %1$s kez. Toplam süre: %2$s. En son %3$s önce kullanıldı." "Erişim: %1$s kez. En son %2$s önce kullanıldı." @@ -137,11 +134,9 @@ "%1$s %3$s önce cihazınızın %2$s özelliğine erişti." "%1$s, %2$s izninize erişmedi." "Ayrıntılı izin kullanımını göster" - - + "Son erişim:%1$s" "İzin verildi" - - + "Yalnızca kullanımdayken izin verilenler" "Reddedildi" "Ayrıntılı kullanımı göster" @@ -165,22 +160,6 @@ "İzin hatırlatıcılar" "%s, konumunuzu kullanıyor" "Bu uygulama, konumunuza her zaman erişebilir. Değiştirmek için dokunun." - "Uygulama geliştirici, verilerinizle ilgili şöyle söylüyor:" - "Bu uygulama geliştiricinin verilerinizi kullanma biçimini beğenmediyseniz izin vermeyebilirsiniz." - "Daha fazla bilgi için %s uygulamasına gidin." - "Buluta yüklenir" - "Açık bir şekilde izin verdiğinizde buluta yüklenir" - "Reklamverenlerle veya işletmelerle paylaşılır" - "Açık bir şekilde izin verdiğinizde reklamverenlerle veya işletmelerle paylaşılır" - "Para kazanmak için kullanılır" - "Açık bir şekilde izin verdiğinizde para kazanmak için kullanılır" - "Sonsuza kadar saklanır ve analiz edilir" - "Belirttiğiniz süre boyunca saklanır ve analiz edilir" - - %s hafta boyunca saklanır ve analiz edilir - 1 hafta boyunca saklanır ve analiz edilir - - "Uygulama geliştirici, uygulamanın verilerinizi nasıl kullandığını belirtmedi." "Yalnızca uygulama kullanılırken" "Hiçbir izin verilmedi" "Hiçbir izin reddedilmedi" @@ -205,10 +184,18 @@ "Müzik uygulaması" "Galeri uygulaması" "Araba modu telefon uygulaması" - "Proxy arama uygulaması" + + "Arama süzme uygulaması" "Arama tamamlayıcı uygulaması" - - + "Yardım uygulaması" + "Car Projection uygulaması" "Not: Cihazınızı yeniden başlatırsanız ve ekran kilidi kullanıyorsanız, cihazınızın kilidini açmadan bu uygulama başlayamaz." + "Hata Ayıklama Verilerini Paylaş" + "Ayrıntılı hata ayıklama verileri paylaşılsın mı?" + "%1$s, hata ayıklama bilgilerini yüklemek istiyor." + "Hata Ayıklama Verilerini Paylaş" + "%1$s, bu cihazda %2$s saat %3$s itibarıyla kaydedilen hata raporunu yüklemek istiyor. Hata raporları cihazınızla ilgili veya uygulamalar tarafından günlüğe kaydedilmiş kişisel bilgiler (örneğin kullanıcı adları, konum verisi, cihaz tanımlayıcılar ve ağ bilgileri) içerir. Hata raporlarını yalnızca bu bilgileri verme konusunda güvendiğiniz kişi ve uygulamalarla paylaşın. %4$s uygulamasının hata raporu yüklemesine izin verilsin mi?" + "İzin ver" + "Reddet" diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml index 1f2182eb8..7e6061b76 100644 --- a/res/values-uk/strings.xml +++ b/res/values-uk/strings.xml @@ -4,9 +4,9 @@ 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. @@ -116,17 +116,14 @@ "Найбільш уживані дозволи за останні 15 хвилин" "Найбільш уживані дозволи за останню хвилину" "Додатки" - - - - + "Відфільтровано за параметром: %1$s" + "Вилучити фільтр" "Фільтр" "Фільтрувати за дозволами" "Найбільше дозволів" "Найбільше сеансів доступу" "Нещодавні сеанси доступу" - - + "Оновити" "Використання дозволів додатка" "Доступ: %1$s раз. Загальна тривалість: %2$s. Востаннє використано %3$s тому." "Доступ: %1$s раз. Востаннє використано %2$s тому." @@ -139,11 +136,9 @@ "Додаток %1$s отримав доступ %3$s тому (%2$s)." "%1$s не приймає дозвіл \"%2$s\"." "Переглянути детальну інформацію про використання дозволів" - - + "Останній сеанс доступу: %1$s" "Дозволено" - - + "Дозволено лише за активності додатка" "Відхилено" "Переглянути дані про використання" @@ -175,24 +170,6 @@ "Нагадування про дозволи" "%s використовує геодані пристрою" "Цей додаток завжди має доступ до геоданих пристрою. Торкніться, щоб змінити це." - "Розробник додатка вказує, що ваші дані можуть:" - "Якщо вам не подобається, як розробник додатка використовує ваші дані, можна скасувати дозвіл." - "Щоб дізнатися більше, перейдіть у додаток \"%s\"." - "завантажуватися в хмару" - "завантажуватися в хмару, коли ви це чітко дозволяєте" - "надаватися рекламодавцям або компаніям" - "надаватися рекламодавцям або компаніям, коли ви це чітко дозволяєте" - "Використовуються для монетизації" - "використовуватися для монетизації, коли ви це чітко дозволяєте" - "завжди зберігатися й аналізуватися" - "Зберігаються й аналізуються протягом указаного вами періоду часу" - - Зберігаються й аналізуються %s тиждень - Зберігаються й аналізуються %s тижні - Зберігаються й аналізуються %s тижнів - Зберігаються й аналізуються %s тижня - - "Розробник додатка не вказує, як використовуються ваші дані." "Лише коли додаток використовується" "Немає наданих дозволів" "Немає відхилених дозволів" @@ -217,10 +194,18 @@ "Додаток Музика" "Додаток Галерея" "Телефонний додаток для режиму авто" - "Додаток для проксі-викликів" + + "Додаток для керування викликами" "Супутній додаток для викликів" - - + "Помічник" + "Додаток для проекції на екран авто" "Примітка. Якщо після перезавантаження ввімкнеться екран блокування, цей додаток не запуститься, доки ви не розблокуєте пристрій." + "Поділитися даними про налагодження" + "Поділитися детальними даними про налагодження?" + "Додаток %1$s хоче завантажити інформацію про налагодження." + "Поділитися даними про налагодження" + "Додаток %1$s запитує, чи можна завантажити повідомлення про помилку, створене на цьому пристрої %3$s %2$s. Повідомлення про помилки містять особисту інформацію про ваш пристрій або відомості, записані додатками, як-от імена користувачів, місцеположення, ідентифікатори пристроїв та інформацію про мережу. Діліться повідомленнями про помилки лише з тими людьми й додатками, яким довіряєте. Дозволити додатку %4$s завантажити повідомлення про помилку?" + "Дозволити" + "Відмовити" diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml index 614eba6d6..c3ada0782 100644 --- a/res/values-ur/strings.xml +++ b/res/values-ur/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "آخر کے 15 منٹ میں اعلٰی اجازت کا استعمال" "آخر کے 1 گھنٹے میں سرفہرست اجازت کا استعمال" "ایپس" - - - - + "فلٹر کردہ بلحاظ: %1$s" + "فلٹر ہٹائیں" "فلٹر کریں بہ لحاظ" "اجازتوں کے لحاظ سے فلٹر کریں" "زیادہ تر اجازتیں" "زیادہ تر رسائی" "حالیہ" - - + "ریفریش کریں" "ایپ کی اجازتوں کا استعمال" "رسائی: %1$s مرتبہ۔ کل دورانیہ: %2$s۔ %3$s پہلے آخری بار استعمال کیا گيا۔" "رسائی: %1$s مرتبہ۔ %2$s پہلے آخری بار استعمال کیا گیا۔" @@ -137,11 +134,9 @@ "%1$s نے %3$s پہلے %2$s تک رسائی حاصل کی۔" "%1$s نے آپ کے %2$s تک رسائی نہیں کی ہے۔" "تفصیلی اجازتوں کا استعمال دیکھیں" - - + "آخری رسائی: %1$s" "اجازت ہے" - - + "صرف استعمال کے دوران اجازت ہے" "مسترد ہو گئی" "تفصیلی استعمال دیکھیں" @@ -165,22 +160,6 @@ "اجازت کی یاددہانیاں" "%s آپ کے مقام کا استعمال کر رہی ہے" "یہ ایپ ہمیشہ آپ کے مقام تک رسائی حاصل کر سکتی ہے۔ تبدیل کرنے کے لیے تھپتھپائیں۔" - "ایپ ڈیولپر کے مطابق آپ کا ڈیٹا ایسا ہو سکتا ہے:" - "اگر آپ کو اس ایپ ڈیولپر کے آپ کا ڈیٹا استعمال کرنے کا طریقہ پسند نہیں ہے تو آپ اجازت کو مسترد کر سکتے ہیں۔" - "مزید معلومات کے لیے %s پر جائيں۔" - "کلاؤڈ میں اپ لوڈ کیا گیا" - "آپ کی جانب سے صَرِيح طور پر اپ لوڈ کی اجازت دیے جانے کے وقت کلاؤڈ میں اپ لوڈ کیا گیا" - "مشتہرین یا کاروباروں کے ساتھ اشتراک کیا گیا" - "آپ کی جانب سے صَرِيح طور پر اشتراک کی اجازت دیے جانے کے وقت مشتہرین یا کاروباروں کے ساتھ اشتراک کیا گیا" - "منیٹائزیشن کیلئے استعمال کیا گیا" - "آپ کی جانب سے صَرِيح طور پر منیٹائزیشن کی اجازت دیے جانے کے وقت اس مقصد کیلئے استعمال کیا گیا" - "ہمیشہ کیلئے محفوظ کیا گیا اور تجزیہ کیا گیا" - "آپ کے وضاحت کردہ دورانیے کیلئے محفوظ اور تجزیہ کیا گیا" - - %s ہفتوں کیلئے محفوظ اور تجزیہ کیا گیا - 1 ہفتے کیلئے محفوظ اور تجزیہ کیا گیا - - "ایپ ڈیولپر نے اس بات کی وضاحت نہیں کی کہ ایپ کیسے آپ کا ڈیٹا استعمال کرتی ہے۔" "صرف اپپ کے زیر استعمال ہونے کے دوران" "کوئی اجازت نہیں دی گئی" "کوئی بھی اجازت مسترد نہیں ہے" @@ -205,10 +184,18 @@ "موسیقی ایپ" "گیلری ایپ" "کار موڈ والی فون ایپ" - "پراکسی کال کرنے کی اپپ" + + "کال اسکریننگ اپپ" "ساتھی اپپ برائے کال" - - + "معاون ایپ" + "‏Car Projection ایپ" "نوٹ: اگر آپ اپنے آلہ کو دوبارہ شروع کرتے ہیں اور آپ کے پاس اسکرین لاک کا سیٹ ہے تو یہ ایپ تب تک شروع نہیں ہو سکتی جب تک آپ اپنا آلہ غیر مقفل نہ کر لیں۔" + "ڈیبگنگ ڈیٹا کا اشتراک کریں" + "ڈیبگنگ کے تفصیلی ڈیٹا کا اشتراک کریں؟" + "%1$s ڈیبگنگ کی معلومات اپ لوڈ کرنا چاہتی ہے۔" + "ڈیبگنگ ڈیٹا کا اشتراک کریں" + "%1$s %2$s کو %3$s پر اس آلہ سے لی گئی بگ رپورٹ اپ لوڈ کرنے کی درخواست کر رہی ہے۔ بگ رپورٹس میں آپ کے آلہ کے بارے میں یا ایپس کے ذریعے لاگ کی گئی ذاتی معلومات، جیسے کہ صارف کے نام، مقام کا ڈیٹا، آلہ کے شناخت کاران اور نیٹ ورک کی معلومات شامل ہوتی ہیں۔ صرف ان ہی لوگوں اور ایپس کے ساتھ بگ رپورٹس کا اشتراک کریں جن پر آپ کو اس معلومات کے تعلق سے بھروسہ ہے۔ %4$s کو بگ رپورٹ اپ لوڈ کرنے کی اجازت دیں؟" + "اجازت دیں" + "رَد کریں" diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml index 585d82ed9..85f47bb55 100644 --- a/res/values-uz/strings.xml +++ b/res/values-uz/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "Oxirgi 15 daqiqada eng koʻp ishlatilganlar" "Oxirgi 1 daqiqada eng koʻp ishlatilganlar" "Ilovalar" - - - - + "Filtrlar: %1$s" + "Filtrni olib tashlash" "Filtrlash" "Ruxsatlar asosida filtrlash" "Eng koʻp ishlatilganlar" "Eng koʻp ishlatilganlar" "Yaqinda" - - + "Yangilash" "Ilovalar uchun ruxsatlar" "Kirish talabi: %1$s marta. Jami foydalanish vaqti: %2$s. Oxirgi marta %3$s oldin foydalanilgan." "Kirish talabi: %1$s marta. Oxirgi marta %2$s oldin foydalanilgan." @@ -137,11 +134,9 @@ "%1$s %3$s oldin %2$s ruxsatidan foydalandi." "%1$s ilovasi uchun %2$s ruxsati berilmagan." "Ruxsatlardan foydalanish haqida batafsil axborotni ochish" - - + "Oxirgi marta ishlatilgan: %1$s" "Taqdim etilgan ruxsat" - - + "Foydalanilayotganda ruxsat beriladi" "Taqdim etilmagan ruxsatlar" "Batafsil statistika" @@ -165,22 +160,6 @@ "Ruxsat eslatmalari" "%s joylashuvingiz axborotidan foydalanmoqda" "Bu ilova joylashuv axborotingizdan foydalana oladi. Oʻzgartirish uchun bosing." - "Ilova ishlab chiquvchisiga koʻra, maʼlumotlaringiz quyidagi maqsadlarda ishlatilishi mumkin:" - "Agar ilova ishlab chiquvchisi maʼlumotlaringizdan qay tarzda foydalanishiga rozi boʻlmasangiz, ruxsat bermang." - "Batafsil axborot olish uchun %s ilovasini oching." - "Bulutdagi xotiraga yuklash" - "Sizning mutloq roziligingiz bilan bulutdagi xotiraga yuklash" - "Reklama beruvchilar va tijoriy kompaniyalarga taqdim etish" - "Sizning mutloq roziligingiz bilan reklama beruvchilar va tijoriy kompaniyalarga taqdim etish" - "Tijoriy maqsadlarda foydalanish" - "Sizning mutloq roziligingiz bilan tijoriy maqsadlarda foydalanish" - "Cheklanmagan vaqtda tahlil uchun saqlash va foydalanish" - "Muayyan vaqt davomida tahlil uchun saqlash va foydalanish" - - %s hafta davomida tahlil uchun saqlash va foydalanish - 1 hafta davomida tahlil uchun saqlash va foydalanish - - "Ilova ishlab chiquvchisi maʼlumotlaringizda ilova qanday foydalanishini bildirmagan." "Faqat ilova faolligida ruxsat berish" "Hech qanday ruxsat berilmagan" "Hech qanday taqiq yoʻq" @@ -205,10 +184,18 @@ "Musiqa ilovasi" "Galereya ilovasi" "Mashina uchun telefon ilovasi" - "Proksi-chaqiruvlar ilovasi" + + "Kiruvchi chaqiruvlar ilovasi" "Chaqiruvlar ilovasiga sherik" - - + "Yordamchi ilova" + "Car Projection ilovasi" "Eslatma: Agar qurilmani qayta ishga tushirsangiz va ekran qulfi sozlangan boʻlsa, bu ilova to qurilmangiz qulfdan chiqarilmaguncha ishga tushmaydi." + "Nosozliklarni aniqlash axborotini ulashish" + "Nosozliklarni aniqlashga oid axborot ulashilsinmi?" + "%1$s ilovasi nosozliklarni aniqlash axborotini yuklamoqchi." + "Nosozliklarni aniqlash axborotini ulashish" + "%1$s ilovasi bu qurilmadan %2$s sanasida %3$s da olingan xatoliklar hisobotini yuklashni talab etmoqda. Xatoliklar hisobotiga foydalanuvchi nomlari, joylashuv axboroti, qurilma identifikatorlari va tarmoq maʼlumotlari kabi qurilmangiz yoki qayd qilingan ilovalar haqida shaxsiy maʼlumotlar kiradi. Bunday maʼlumotlarni faqat ishonchli odamlar va ilovalarga yuboring. %4$s ilovasiga xatoliklar hisobotini yuklashga ruxsat berilsinmi?" + "Ruxsat" + "Rad etish" diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml index 365755616..47505a1f3 100644 --- a/res/values-vi/strings.xml +++ b/res/values-vi/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "Cách sử dụng quyền phổ biến nhất trong 15 phút qua" "Cách sử dụng quyền phổ biến nhất trong 1 phút qua" "Ứng dụng" - - - - + "Đã lọc bởi: %1$s" + "Xóa bộ lọc" "Lọc theo" "Lọc theo quyền" "Nhiều quyền nhất" "Nhiều lần truy cập nhất" "Gần đây" - - + "Làm mới" "Sử dụng quyền ứng dụng" "Truy cập: %1$s lần. Tổng thời gian: %2$s. Sử dụng lần gần đây nhất vào %3$s trước." "Truy cập: %1$s lần. Sử dụng lần gần đây nhất vào %2$s trước." @@ -137,11 +134,9 @@ "%1$s đã truy cập vào %2$s %3$s trước." "%1$s chưa truy cập vào %2$s của bạn." "Xem mức sử dụng quyền chi tiết" - - + "Lần truy cập gần đây nhất: %1$s" "Được phép" - - + "Chỉ cho phép khi đang sử dụng" "Bị từ chối" "Xem mức sử dụng chi tiết" @@ -165,22 +160,6 @@ "Lời nhắc về quyền" "%s đã sử dụng thông tin vị trí của bạn" "Ứng dụng này luôn có thể truy cập vào thông tin vị trí của bạn. Hãy nhấn để thay đổi." - "Nhà phát triển ứng dụng cho biết dữ liệu của bạn có thể được:" - "Nếu không thích cách nhà phát triển ứng dụng này sử dụng dữ liệu của mình, thì bạn có thể từ chối cấp quyền." - "Truy cập vào %s để biết thêm thông tin." - "Tải lên đám mây" - "Tải lên đám mây khi bạn cho phép rõ ràng" - "Chia sẻ với các nhà quảng cáo hoặc doanh nghiệp" - "Chia sẻ với các nhà quảng cáo hoặc doanh nghiệp khi bạn cho phép rõ ràng" - "Dùng để kiếm tiền" - "Dùng để kiếm tiền khi bạn cho phép rõ ràng" - "Lưu và phân tích vĩnh viễn" - "Lưu và phân tích trong thời gian bạn chỉ định" - - Lưu và phân tích trong %s tuần - Lưu và phân tích trong 1 tuần - - "Nhà phát triển ứng dụng không chỉ rõ cách ứng dụng sử dụng dữ liệu của bạn." "Chỉ khi đang sử dụng ứng dụng" "Chưa cấp quyền nào" "Chưa từ chối quyền nào" @@ -205,10 +184,18 @@ "Ứng dụng âm nhạc" "Ứng dụng thư viện" "Ứng dụng điện thoại cho chế độ ô tô" - "Ứng dụng gọi điện qua proxy" + + "Ứng dụng sàng lọc cuộc gọi" "Ứng dụng đồng hành cuộc gọi" - - + "Ứng dụng trợ lý" + "Ứng dụng Chiếu trên ô tô" "Lưu ý: Nếu bạn khởi động lại thiết bị và đặt khóa màn hình, thì ứng dụng này sẽ không thể khởi động cho đến khi bạn mở khóa thiết bị." + "Chia sẻ dữ liệu gỡ lỗi" + "Bạn muốn chia sẻ dữ liệu gỡ lỗi chi tiết?" + "%1$s muốn tải thông tin gỡ lỗi lên." + "Chia sẻ dữ liệu gỡ lỗi" + "%1$s đang yêu cầu tải lên từ thiết bị này một báo cáo lỗi được thực hiện vào %2$s lúc %3$s. Báo cáo lỗi bao gồm thông tin cá nhân về thiết bị của bạn hoặc do ứng dụng ghi nhật ký, ví dụ như tên người dùng, dữ liệu vị trí, giá trị nhận dạng thiết bị và thông tin mạng. Chỉ chia sẻ báo cáo lỗi với người và ứng dụng bạn tin cậy đối với thông tin này. Bạn muốn cho phép %4$s tải báo cáo lỗi lên?" + "Cho phép" + "Từ chối" diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml index 57806e197..f574bcc23 100644 --- a/res/values-zh-rCN/strings.xml +++ b/res/values-zh-rCN/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "过去 15 分钟内常用权限的使用频率" "过去 1 分钟内常用权限的使用频率" "应用" - - - - + "过滤条件:%1$s" + "移除过滤条件" "过滤条件" "按权限过滤" "使用的权限数量最多" "访问次数最多" "最近" - - + "刷新" "应用权限使用情况" "访问次数:%1$s 次。总时长:%2$s。上次使用时间:%3$s前。" "访问次数:%1$s 次。上次使用时间:%2$s前。" @@ -137,11 +134,9 @@ "%1$s %3$s前访问过您的%2$s。" "%1$s尚未取得您的%2$s访问权限。" "查看权限使用情况详情" - - + "上次访问时间:%1$s" "已允许" - - + "仅在使用时允许" "已拒绝" "查看详细的使用情况信息" @@ -165,22 +160,6 @@ "权限提醒" "%s一直在使用您的位置信息" "此应用随时可以使用您的位置信息。点按即可更改。" - "应用开发者表示可能会将您的数据:" - "如果您对此应用开发者使用您数据的方式不满,可以拒绝授予权限。" - "转到%s查看更多信息。" - "上传到云端" - "在获得您明确授权后将数据上传到云端" - "与广告客户或商家分享您的数据" - "在获得您明确授权后与广告客户或商家分享您的数据" - "用于盈利" - "在获得您明确授权后将数据用于盈利" - "无限期保存及分析数据" - "保存及进行分析(在您指定的时间内)" - - 保存及进行分析(在 %s 周内) - 保存及进行分析(在 1 周内) - - "应用开发者未指定这个应用使用您数据的方式。" "仅在使用该应用期间允许" "未允许任何权限" "未拒绝任何权限" @@ -205,10 +184,18 @@ "音乐应用" "图库应用" "车载模式手机应用" - "代理通话应用" + + "选接电话应用" "通话配套应用" - - + "辅助应用" + "汽车投影应用" "注意:如果您重启设备并设置了屏幕锁定,则必须将设备解锁才能运行此应用。" + "分享调试数据" + "是否分享详细调试数据?" + "%1$s请求上传调试信息。" + "分享调试数据" + "%1$s正在请求上传此设备在 %2$s%3$s 获取的错误报告。错误报告包含与您设备有关或由应用记录的个人信息,例如:用户名、位置数据、设备标识符和网络信息。请务必只与您认为可以向其透露这些信息的人和应用分享错误报告。是否允许%4$s上传错误报告?" + "允许" + "拒绝" diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml index 7f9774ecd..43dc1d9f5 100644 --- a/res/values-zh-rHK/strings.xml +++ b/res/values-zh-rHK/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "最常用權限在過去 15 分鐘內的使用情況" "最常用權限在過去 1 分鐘內的使用情況" "應用程式" - - - - + "篩選條件:%1$s" + "移除篩選器" "篩選方式" "按權限篩選" "使用最多權限" "存取次數最多" "最近" - - + "重新整理" "應用程式權限使用情況" "存取次數:%1$s 次。總時長:%2$s。上次使用時間:%3$s前。" "存取次數:%1$s 次。上次使用時間:%2$s前。" @@ -137,11 +134,9 @@ "「%1$s」在 %3$s前存取了您的%2$s。" "「%1$s」沒有存取%2$s。" "查看詳細的權限使用情況" - - + "上次存取時間:%1$s" "已允許" - - + "只在使用時允許" "已拒絕" "查看詳細的使用情況" @@ -165,22 +160,6 @@ "權限提醒" "%s在使用您的位置資訊" "此應用程式可隨時存取您的位置資訊。輕按即可變更權限。" - "應用程式開發人員表示您的資料可能:" - "如果您不喜歡應用程式開發人員使用資料的方式,則可拒絕授予權限。" - "前往「%s」查看更多資料。" - "已上載至雲端" - "已在您明確同意的情況下上載至雲端" - "已與廣告客戶或商家分享" - "已在您明確同意的情況下,與廣告客戶或商家分享" - "已用於營利" - "已在您明確同意的情況下用於營利" - "已永久儲存和分析" - "已在您指定的時段儲存和分析" - - 已儲存和分析 %s 星期 - 已儲存和分析 1 星期 - - "應用程式開發人員沒有註明應用程式如何使用您的資料。" "只在使用應用程式時" "不允許任何權限" "沒有拒絕任何權限" @@ -205,10 +184,18 @@ "音樂應用程式" "相片集應用程式" "車用模式手機應用程式" - "Proxy 通話應用程式" + + "來電篩選應用程式" "通話隨附應用程式" - - + "小幫手應用程式" + "「汽車投影」應用程式" "請注意:如果您重新啟動裝置並設定了螢幕鎖定,就必須先將裝置解鎖,才可執行這個應用程式。" + "分享偵錯資料" + "要分享詳細的偵錯資料嗎?" + "「%1$s」要求上載偵錯資料。" + "分享偵錯資料" + "「%1$s」要求上載此裝置於 %2$s%3$s傳送的錯誤報告。錯誤報告包括您的裝置或應用程式記錄的個人資料,例如使用者名稱、位置資料、裝置識別碼和網絡資訊。只與您信任可存取這些資料的使用者和應用程式分享錯誤報告。要允許「%4$s」上載錯誤報告嗎?" + "允許" + "拒絕" diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml index 26431e085..add445b62 100644 --- a/res/values-zh-rTW/strings.xml +++ b/res/values-zh-rTW/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "過去 15 分鐘內常用權限的使用頻率" "過去 1 分鐘內常用權限的使用頻率" "應用程式" - - - - + "篩選依據:%1$s" + "移除篩選器" "篩選依據" "依權限篩選" "使用的權限數量最多" "存取次數最多" "最近使用過的存取權" - - + "重新整理" "應用程式權限使用情況" "使用次數:%1$s 次。總時間長度:%2$s。上次使用時間:%3$s前。" "使用次數:%1$s 次。上次使用時間:%2$s前。" @@ -137,11 +134,9 @@ "「%1$s」在 %3$s前存取了你的%2$s。" "「%1$s」尚未取得你的%2$s存取權。" "查看詳細的權限使用情況" - - + "上次存取時間:%1$s" "已允許" - - + "僅在使用時允許" "已拒絕" "查看詳細使用資料" @@ -165,22 +160,6 @@ "權限提醒" "「%s」正在使用你的位置資訊" "這個應用程式隨時都能存取你的位置資訊。輕觸即可變更設定。" - "應用程式開發人員可能會將你的資料:" - "如果你對應用程式開發人員使用資料的方式不滿意,可以拒絕授予權限。" - "前往「%s」瞭解詳情。" - "上傳到雲端" - "上傳到雲端 (當你明確允許時)" - "與廣告客戶或商家分享" - "與廣告客戶或商家分享 (當你明確允許時)" - "用於營利" - "用於營利 (當你明確允許時)" - "儲存並用於分析 (永久)" - "儲存並用於分析 (在你指定的時間內)" - - 儲存並用於分析 (%s 週) - 儲存並用於分析 (1 週) - - "應用程式開發人員並未指定這個應用程式如何使用你的資料。" "僅在應用程式使用期間" "未授予任何權限" "未拒絕授予任何權限" @@ -205,10 +184,18 @@ "音樂應用程式" "圖片庫應用程式" "車用模式手機應用程式" - "Proxy 撥號應用程式" + + "來電過濾應用程式" "通話隨附應用程式" - - + "小幫手應用程式" + "車輛投影應用程式" "注意:如果你重新啟動裝置並設定了螢幕鎖定,你必須先將裝置解鎖,才能執行這個應用程式。" + "分享除錯資料" + "要分享詳細的除錯資料嗎?" + "「%1$s」要求上傳除錯資訊。" + "分享除錯資料" + "「%1$s」要求上傳這個裝置在 %2$s%3$s 取得的錯誤報告。錯誤報告包含裝置的相關個人資訊或由應用程式記錄的個人資訊,例如:使用者名稱、位置資料、裝置 ID 和網路資訊。請務必只與你信任的使用者和應用程式分享這項資訊。要允許「%4$s」上傳錯誤報告嗎?" + "允許" + "拒絕" diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml index b6a38efc2..d086817ff 100644 --- a/res/values-zu/strings.xml +++ b/res/values-zu/strings.xml @@ -4,9 +4,9 @@ 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. @@ -114,17 +114,14 @@ "Ukusetshenziswa kwemvume ephezulu kumaminithi okugcina angu-15" "Ukusetshenziswa kwemvume ephezulu kuminithi lokugcina elingu-1" "Izinhlelo zokusebenza" - - - - + "Kuhlungwe ngalokhu: %1$s" + "Susa isihlungi" "Hlunga nge-" "Hlunga ngezimvume" "Izimvume eziningi" "Efinyelelwe kakhulu" "Okwakamuva" - - + "Vuselela" "Ukusetshenziswa kwezimvume zohlelo lokusebenza" "Ukufinyelela: %1$s izikhathi. Ubude besikhathi: %2$s. Kugcinwe ukusetshenziswa u-%3$s owedlule." "Ukufinyelela: %1$s izikhathi. Kugcinwe ukusetshenziswa u-%2$s odlule." @@ -137,11 +134,9 @@ "%1$s ufinyelele u-%2$s yakho isikhathi esingu-%3$s esedlule." "%1$s ayifinyelele i-%2$s yakho." "Buka ukusetshenziswa kwezimvume ezinemininingwane" - - + "Kugcine ukufinyelelwa: %1$s" "Kuvumelekile" - - + "Kuvunyelwe kuphela ngenkathi kusetshenziswa" "Kunqatshiwe" "Bona ukusebenzisa okunemininingwane" @@ -165,22 +160,6 @@ "Izikhumbuzi zemvume" "I-%s ibikade isebenzisa indawo yakho" "Lolu hlelo lokusebenza lungahlala lufinyelela indawo yakho. Thepha ukuze ushintshe." - "Unjiniyela wohlelo lokusebenza uthi idatha yakho ingaba:" - "Uma ungathandi indlela unjiniyela walolu hlelo lokusebenza asebenzisa ngayo idatha yakho unganqabela imvume." - "Iya ku-%s ngolwazi olungeziwe." - "Kulayishwe emafini" - "Kulayishwe emafini uma ukuvumela ngokucacile" - "Kwabiwe nabakhangisi noma amabhizinisi" - "Kwabiwe nabakhangisi noma amabhizinisi uma ukuvumela ngokucacile" - "Kusetshenziselwa ukwenza imali" - "Kusetshenziselwa ukwenza imali uma ukuvumela ngokucacile" - "Kulondolozwe futhi kwahlaziywa unaphakade" - "Kulondolozwe futhi kwahlaziyelwa ubude obucacisile" - - Kulondoloziwe futhi kwahlaziyelwa amaviki angu-%s - Kulondoloziwe futhi kwahlaziyelwa amaviki angu-%s - - "Unjiniyela wohlelo lokusebenza akacacisanga indlela uhlelo lokusebenza lisebenzisa idatha yakho." "Kuphela ngenkathi uhlelo lokusebenza lusebenza" "Azikho izimvume ezivunyelwe" "Azikho izimvume ezinqatshelwe" @@ -205,10 +184,18 @@ "Uhlelo lokusebenza lomculo" "Uhlelo lokusebenza lwegalari" "I-app yefoni yemoti yemoto" - "I-app yokushaya yommeleli" + + "I-app lokuskrina lokushaya" "I-app lokuhambisana lokushaya" - - + "Uhlelo lokusebenza lokusiza" + "Uhlelo lokusebenza lokuphrojektha kwemoto" "Qaphela: Uma uqala kabusha idivayisi yakho futhi usethe ukukhiya kwesikrini, lolu hlelo lokusebenza alukwazi ukuqala uze uvule idivayisi yakho." + "Yabelana ngedatha yokususa iphutha" + "Yabelana ngedatha enemininingwane yokususa iphutha?" + "I-%1$s ingathanda ukulayisha ulwazi lokususa iphutha." + "Yabelana ngedatha yokususa iphutha" + "I-%1$s icela ukulayisha umbiko wesiphazamisi kusukela kule divayisi othathwe ngomhla ka-%2$s ngo-%3$s. Imibiko yesiphazamisi ifaka ulwazi lomuntu siqu olumayelana nedivayisi yakho noma olufakwe ngezinhlelo zokusebenza, isibonelo, amagama abasebenzisi, idatha yendawo, izikhombi zedivayisi, nolwazi lwedivayisi. Yabelana kuphela ngemibiko yesiphazamisi nabantu nezinhlelo zokusebenza ozithembayo ngalolu lwazi. Vumela i-%4$s ukuthi ilayishe umbiko wesiphazamisi?" + "Vumela" + "Phika" diff --git a/test/instrumentation/res/values-af/strings.xml b/test/instrumentation/res/values-af/strings.xml new file mode 100644 index 000000000..42d6d17e6 --- /dev/null +++ b/test/instrumentation/res/values-af/strings.xml @@ -0,0 +1,20 @@ + + + + + "Toestemmingbeheerdertoetse" + diff --git a/test/instrumentation/res/values-am/strings.xml b/test/instrumentation/res/values-am/strings.xml new file mode 100644 index 000000000..ecb944688 --- /dev/null +++ b/test/instrumentation/res/values-am/strings.xml @@ -0,0 +1,20 @@ + + + + + "የፈቃድ ተቆጣጣሪ ሙከራዎች" + diff --git a/test/instrumentation/res/values-ar/strings.xml b/test/instrumentation/res/values-ar/strings.xml new file mode 100644 index 000000000..0e4991ebb --- /dev/null +++ b/test/instrumentation/res/values-ar/strings.xml @@ -0,0 +1,20 @@ + + + + + "اختبارات وحدة التحكم في الأذونات" + diff --git a/test/instrumentation/res/values-as/strings.xml b/test/instrumentation/res/values-as/strings.xml new file mode 100644 index 000000000..1622a1631 --- /dev/null +++ b/test/instrumentation/res/values-as/strings.xml @@ -0,0 +1,20 @@ + + + + + "অনুমতি নিয়ন্ত্ৰক পৰীক্ষা" + diff --git a/test/instrumentation/res/values-az/strings.xml b/test/instrumentation/res/values-az/strings.xml new file mode 100644 index 000000000..4b51b3de3 --- /dev/null +++ b/test/instrumentation/res/values-az/strings.xml @@ -0,0 +1,20 @@ + + + + + "İcazə Nəzarətçisi Testləri" + diff --git a/test/instrumentation/res/values-b+sr+Latn/strings.xml b/test/instrumentation/res/values-b+sr+Latn/strings.xml new file mode 100644 index 000000000..72b23b221 --- /dev/null +++ b/test/instrumentation/res/values-b+sr+Latn/strings.xml @@ -0,0 +1,20 @@ + + + + + "Testiranja kontrolera dozvola" + diff --git a/test/instrumentation/res/values-be/strings.xml b/test/instrumentation/res/values-be/strings.xml new file mode 100644 index 000000000..27cda45d2 --- /dev/null +++ b/test/instrumentation/res/values-be/strings.xml @@ -0,0 +1,20 @@ + + + + + "Тэсціраванне кантралёра дазволаў" + diff --git a/test/instrumentation/res/values-bg/strings.xml b/test/instrumentation/res/values-bg/strings.xml new file mode 100644 index 000000000..2c73cec1c --- /dev/null +++ b/test/instrumentation/res/values-bg/strings.xml @@ -0,0 +1,20 @@ + + + + + "Тестове за управление на разрешения" + diff --git a/test/instrumentation/res/values-bn/strings.xml b/test/instrumentation/res/values-bn/strings.xml new file mode 100644 index 000000000..33d1181e3 --- /dev/null +++ b/test/instrumentation/res/values-bn/strings.xml @@ -0,0 +1,20 @@ + + + + + "অনুমতি নিয়ন্ত্রক পরীক্ষা" + diff --git a/test/instrumentation/res/values-bs/strings.xml b/test/instrumentation/res/values-bs/strings.xml new file mode 100644 index 000000000..e0c6f1c5d --- /dev/null +++ b/test/instrumentation/res/values-bs/strings.xml @@ -0,0 +1,20 @@ + + + + + "Testovi za odobrenja kontrolera" + diff --git a/test/instrumentation/res/values-ca/strings.xml b/test/instrumentation/res/values-ca/strings.xml new file mode 100644 index 000000000..c6a3e7d00 --- /dev/null +++ b/test/instrumentation/res/values-ca/strings.xml @@ -0,0 +1,20 @@ + + + + + "Proves del controlador de permisos" + diff --git a/test/instrumentation/res/values-cs/strings.xml b/test/instrumentation/res/values-cs/strings.xml new file mode 100644 index 000000000..bdb901f1d --- /dev/null +++ b/test/instrumentation/res/values-cs/strings.xml @@ -0,0 +1,20 @@ + + + + + "Testy správce oprávnění" + diff --git a/test/instrumentation/res/values-da/strings.xml b/test/instrumentation/res/values-da/strings.xml new file mode 100644 index 000000000..aa7234de6 --- /dev/null +++ b/test/instrumentation/res/values-da/strings.xml @@ -0,0 +1,20 @@ + + + + + "Test af tilladelsesstyring" + diff --git a/test/instrumentation/res/values-de/strings.xml b/test/instrumentation/res/values-de/strings.xml new file mode 100644 index 000000000..4394d8f7d --- /dev/null +++ b/test/instrumentation/res/values-de/strings.xml @@ -0,0 +1,20 @@ + + + + + "Tests zur Berechtigungssteuerung" + diff --git a/test/instrumentation/res/values-el/strings.xml b/test/instrumentation/res/values-el/strings.xml new file mode 100644 index 000000000..db0cb225e --- /dev/null +++ b/test/instrumentation/res/values-el/strings.xml @@ -0,0 +1,20 @@ + + + + + "Δοκιμές εργαλείου ελέγχου αδειών" + diff --git a/test/instrumentation/res/values-en-rAU/strings.xml b/test/instrumentation/res/values-en-rAU/strings.xml new file mode 100644 index 000000000..8ed526400 --- /dev/null +++ b/test/instrumentation/res/values-en-rAU/strings.xml @@ -0,0 +1,20 @@ + + + + + "Permission Controller Tests" + diff --git a/test/instrumentation/res/values-en-rCA/strings.xml b/test/instrumentation/res/values-en-rCA/strings.xml new file mode 100644 index 000000000..8ed526400 --- /dev/null +++ b/test/instrumentation/res/values-en-rCA/strings.xml @@ -0,0 +1,20 @@ + + + + + "Permission Controller Tests" + diff --git a/test/instrumentation/res/values-en-rGB/strings.xml b/test/instrumentation/res/values-en-rGB/strings.xml new file mode 100644 index 000000000..8ed526400 --- /dev/null +++ b/test/instrumentation/res/values-en-rGB/strings.xml @@ -0,0 +1,20 @@ + + + + + "Permission Controller Tests" + diff --git a/test/instrumentation/res/values-en-rIN/strings.xml b/test/instrumentation/res/values-en-rIN/strings.xml new file mode 100644 index 000000000..8ed526400 --- /dev/null +++ b/test/instrumentation/res/values-en-rIN/strings.xml @@ -0,0 +1,20 @@ + + + + + "Permission Controller Tests" + diff --git a/test/instrumentation/res/values-en-rXC/strings.xml b/test/instrumentation/res/values-en-rXC/strings.xml new file mode 100644 index 000000000..efe7fdb2c --- /dev/null +++ b/test/instrumentation/res/values-en-rXC/strings.xml @@ -0,0 +1,20 @@ + + + + + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‏‎‎‎‏‎‎‏‎‏‏‏‏‎‎‏‎‏‎‎‎‎‏‏‏‎‎‎‏‎‏‎‎‏‎‎‏‎‎‎‎‎‎‎‎‏‏‎‏‏‏‎‎‏‎Permission Controller Tests‎‏‎‎‏‎" + diff --git a/test/instrumentation/res/values-es-rUS/strings.xml b/test/instrumentation/res/values-es-rUS/strings.xml new file mode 100644 index 000000000..37e1b519d --- /dev/null +++ b/test/instrumentation/res/values-es-rUS/strings.xml @@ -0,0 +1,20 @@ + + + + + "Pruebas del controlador de permisos" + diff --git a/test/instrumentation/res/values-es/strings.xml b/test/instrumentation/res/values-es/strings.xml new file mode 100644 index 000000000..722310ec2 --- /dev/null +++ b/test/instrumentation/res/values-es/strings.xml @@ -0,0 +1,20 @@ + + + + + "Pruebas de controlador de permisos" + diff --git a/test/instrumentation/res/values-et/strings.xml b/test/instrumentation/res/values-et/strings.xml new file mode 100644 index 000000000..e0eca4c76 --- /dev/null +++ b/test/instrumentation/res/values-et/strings.xml @@ -0,0 +1,20 @@ + + + + + "Lubade kontrolleri testid" + diff --git a/test/instrumentation/res/values-eu/strings.xml b/test/instrumentation/res/values-eu/strings.xml new file mode 100644 index 000000000..8ed526400 --- /dev/null +++ b/test/instrumentation/res/values-eu/strings.xml @@ -0,0 +1,20 @@ + + + + + "Permission Controller Tests" + diff --git a/test/instrumentation/res/values-fa/strings.xml b/test/instrumentation/res/values-fa/strings.xml new file mode 100644 index 000000000..db0c0a3b1 --- /dev/null +++ b/test/instrumentation/res/values-fa/strings.xml @@ -0,0 +1,20 @@ + + + + + "تست‌های کنترل‌کننده مجوز" + diff --git a/test/instrumentation/res/values-fi/strings.xml b/test/instrumentation/res/values-fi/strings.xml new file mode 100644 index 000000000..d2db0a51a --- /dev/null +++ b/test/instrumentation/res/values-fi/strings.xml @@ -0,0 +1,20 @@ + + + + + "Käyttölupien tarkistukset" + diff --git a/test/instrumentation/res/values-fr-rCA/strings.xml b/test/instrumentation/res/values-fr-rCA/strings.xml new file mode 100644 index 000000000..35e10b5fd --- /dev/null +++ b/test/instrumentation/res/values-fr-rCA/strings.xml @@ -0,0 +1,20 @@ + + + + + "Tests de contrôleur d\'autorisation" + diff --git a/test/instrumentation/res/values-fr/strings.xml b/test/instrumentation/res/values-fr/strings.xml new file mode 100644 index 000000000..177340852 --- /dev/null +++ b/test/instrumentation/res/values-fr/strings.xml @@ -0,0 +1,20 @@ + + + + + "Tests du contrôleur d\'autorisations" + diff --git a/test/instrumentation/res/values-gl/strings.xml b/test/instrumentation/res/values-gl/strings.xml new file mode 100644 index 000000000..c90655726 --- /dev/null +++ b/test/instrumentation/res/values-gl/strings.xml @@ -0,0 +1,20 @@ + + + + + "Probas do controlador de permisos" + diff --git a/test/instrumentation/res/values-gu/strings.xml b/test/instrumentation/res/values-gu/strings.xml new file mode 100644 index 000000000..0beb481d3 --- /dev/null +++ b/test/instrumentation/res/values-gu/strings.xml @@ -0,0 +1,20 @@ + + + + + "પરવાનગી નિયંત્રક પરીક્ષણ" + diff --git a/test/instrumentation/res/values-hi/strings.xml b/test/instrumentation/res/values-hi/strings.xml new file mode 100644 index 000000000..8daec63b3 --- /dev/null +++ b/test/instrumentation/res/values-hi/strings.xml @@ -0,0 +1,20 @@ + + + + + "अनुमति नियंत्रक टेस्ट" + diff --git a/test/instrumentation/res/values-hr/strings.xml b/test/instrumentation/res/values-hr/strings.xml new file mode 100644 index 000000000..beb8d7330 --- /dev/null +++ b/test/instrumentation/res/values-hr/strings.xml @@ -0,0 +1,20 @@ + + + + + "Testovi za upravljač dopuštenjima" + diff --git a/test/instrumentation/res/values-hu/strings.xml b/test/instrumentation/res/values-hu/strings.xml new file mode 100644 index 000000000..31bc80ee0 --- /dev/null +++ b/test/instrumentation/res/values-hu/strings.xml @@ -0,0 +1,20 @@ + + + + + "Engedélyvezérlési tesztek" + diff --git a/test/instrumentation/res/values-hy/strings.xml b/test/instrumentation/res/values-hy/strings.xml new file mode 100644 index 000000000..e932640fc --- /dev/null +++ b/test/instrumentation/res/values-hy/strings.xml @@ -0,0 +1,20 @@ + + + + + "Թույլտվությունների վերահսկիչի փորձարկումներ" + diff --git a/test/instrumentation/res/values-in/strings.xml b/test/instrumentation/res/values-in/strings.xml new file mode 100644 index 000000000..0bc175c72 --- /dev/null +++ b/test/instrumentation/res/values-in/strings.xml @@ -0,0 +1,20 @@ + + + + + "Tes Pengontrol Izin" + diff --git a/test/instrumentation/res/values-is/strings.xml b/test/instrumentation/res/values-is/strings.xml new file mode 100644 index 000000000..5579a58b8 --- /dev/null +++ b/test/instrumentation/res/values-is/strings.xml @@ -0,0 +1,20 @@ + + + + + "Prófanir heimildastýringar" + diff --git a/test/instrumentation/res/values-it/strings.xml b/test/instrumentation/res/values-it/strings.xml new file mode 100644 index 000000000..6ba0a7b49 --- /dev/null +++ b/test/instrumentation/res/values-it/strings.xml @@ -0,0 +1,20 @@ + + + + + "Test di app di controllo autorizzazioni" + diff --git a/test/instrumentation/res/values-iw/strings.xml b/test/instrumentation/res/values-iw/strings.xml new file mode 100644 index 000000000..b18938393 --- /dev/null +++ b/test/instrumentation/res/values-iw/strings.xml @@ -0,0 +1,20 @@ + + + + + "בדיקות של בקר הרשאות" + diff --git a/test/instrumentation/res/values-ja/strings.xml b/test/instrumentation/res/values-ja/strings.xml new file mode 100644 index 000000000..978ed3016 --- /dev/null +++ b/test/instrumentation/res/values-ja/strings.xml @@ -0,0 +1,20 @@ + + + + + "権限コントローラ テスト" + diff --git a/test/instrumentation/res/values-ka/strings.xml b/test/instrumentation/res/values-ka/strings.xml new file mode 100644 index 000000000..584103a96 --- /dev/null +++ b/test/instrumentation/res/values-ka/strings.xml @@ -0,0 +1,20 @@ + + + + + "ნებართვების კონტროლერის ტესტები" + diff --git a/test/instrumentation/res/values-kk/strings.xml b/test/instrumentation/res/values-kk/strings.xml new file mode 100644 index 000000000..edf803ca4 --- /dev/null +++ b/test/instrumentation/res/values-kk/strings.xml @@ -0,0 +1,20 @@ + + + + + "Рұқсат контроллерінің сынақтары" + diff --git a/test/instrumentation/res/values-km/strings.xml b/test/instrumentation/res/values-km/strings.xml new file mode 100644 index 000000000..b22811dd4 --- /dev/null +++ b/test/instrumentation/res/values-km/strings.xml @@ -0,0 +1,20 @@ + + + + + "ការធ្វើតេស្ត​កម្មវិធីគ្រប់គ្រង​ការអនុញ្ញាត" + diff --git a/test/instrumentation/res/values-kn/strings.xml b/test/instrumentation/res/values-kn/strings.xml new file mode 100644 index 000000000..8d0dbf90b --- /dev/null +++ b/test/instrumentation/res/values-kn/strings.xml @@ -0,0 +1,20 @@ + + + + + "ಅನುಮತಿ ನಿಯಂತ್ರಕ ಪರೀಕ್ಷೆಗಳು" + diff --git a/test/instrumentation/res/values-ko/strings.xml b/test/instrumentation/res/values-ko/strings.xml new file mode 100644 index 000000000..584831287 --- /dev/null +++ b/test/instrumentation/res/values-ko/strings.xml @@ -0,0 +1,20 @@ + + + + + "권한 관리자 테스트" + diff --git a/test/instrumentation/res/values-ky/strings.xml b/test/instrumentation/res/values-ky/strings.xml new file mode 100644 index 000000000..682a2e991 --- /dev/null +++ b/test/instrumentation/res/values-ky/strings.xml @@ -0,0 +1,20 @@ + + + + + "Уруксаттарды көзөмөлдөгүч колдонмосунун сыноолору" + diff --git a/test/instrumentation/res/values-lo/strings.xml b/test/instrumentation/res/values-lo/strings.xml new file mode 100644 index 000000000..8eff106e2 --- /dev/null +++ b/test/instrumentation/res/values-lo/strings.xml @@ -0,0 +1,20 @@ + + + + + "ການທົດສອບຕົວຄວບຄຸມສິດອະນຸຍາດ" + diff --git a/test/instrumentation/res/values-lt/strings.xml b/test/instrumentation/res/values-lt/strings.xml new file mode 100644 index 000000000..ebc21f785 --- /dev/null +++ b/test/instrumentation/res/values-lt/strings.xml @@ -0,0 +1,20 @@ + + + + + "Leidimų valdiklio bandymai" + diff --git a/test/instrumentation/res/values-lv/strings.xml b/test/instrumentation/res/values-lv/strings.xml new file mode 100644 index 000000000..34c775b20 --- /dev/null +++ b/test/instrumentation/res/values-lv/strings.xml @@ -0,0 +1,20 @@ + + + + + "Atļauju datu pārziņa testi" + diff --git a/test/instrumentation/res/values-mk/strings.xml b/test/instrumentation/res/values-mk/strings.xml new file mode 100644 index 000000000..e4f282842 --- /dev/null +++ b/test/instrumentation/res/values-mk/strings.xml @@ -0,0 +1,20 @@ + + + + + "Тестови на Permission Controller" + diff --git a/test/instrumentation/res/values-ml/strings.xml b/test/instrumentation/res/values-ml/strings.xml new file mode 100644 index 000000000..d387118f9 --- /dev/null +++ b/test/instrumentation/res/values-ml/strings.xml @@ -0,0 +1,20 @@ + + + + + "അനുമതി കൺട്രോളർ ടെസ്‌റ്റുകൾ" + diff --git a/test/instrumentation/res/values-mn/strings.xml b/test/instrumentation/res/values-mn/strings.xml new file mode 100644 index 000000000..5be4f4650 --- /dev/null +++ b/test/instrumentation/res/values-mn/strings.xml @@ -0,0 +1,20 @@ + + + + + "Зөвшөөрөл хянагчийн туршилт" + diff --git a/test/instrumentation/res/values-mr/strings.xml b/test/instrumentation/res/values-mr/strings.xml new file mode 100644 index 000000000..9fed04cfe --- /dev/null +++ b/test/instrumentation/res/values-mr/strings.xml @@ -0,0 +1,20 @@ + + + + + "परवानगी नियंत्रक चाचण्या" + diff --git a/test/instrumentation/res/values-ms/strings.xml b/test/instrumentation/res/values-ms/strings.xml new file mode 100644 index 000000000..4c06334a6 --- /dev/null +++ b/test/instrumentation/res/values-ms/strings.xml @@ -0,0 +1,20 @@ + + + + + "Ujian Pengawal Kebenaran" + diff --git a/test/instrumentation/res/values-my/strings.xml b/test/instrumentation/res/values-my/strings.xml new file mode 100644 index 000000000..7812ef4c5 --- /dev/null +++ b/test/instrumentation/res/values-my/strings.xml @@ -0,0 +1,20 @@ + + + + + "ခွင့်ပြုချက် ထိန်းချုပ်စနစ် စစ်ဆေးမှုများ" + diff --git a/test/instrumentation/res/values-nb/strings.xml b/test/instrumentation/res/values-nb/strings.xml new file mode 100644 index 000000000..9f44bd3e8 --- /dev/null +++ b/test/instrumentation/res/values-nb/strings.xml @@ -0,0 +1,20 @@ + + + + + "Tester for tillatelseskontrollør" + diff --git a/test/instrumentation/res/values-ne/strings.xml b/test/instrumentation/res/values-ne/strings.xml new file mode 100644 index 000000000..97f6406b5 --- /dev/null +++ b/test/instrumentation/res/values-ne/strings.xml @@ -0,0 +1,20 @@ + + + + + "अनुमति नियन्त्रकसम्बन्धी परीक्षणहरू" + diff --git a/test/instrumentation/res/values-nl/strings.xml b/test/instrumentation/res/values-nl/strings.xml new file mode 100644 index 000000000..c27934443 --- /dev/null +++ b/test/instrumentation/res/values-nl/strings.xml @@ -0,0 +1,20 @@ + + + + + "Tests voor machtigingscontroller" + diff --git a/test/instrumentation/res/values-or/strings.xml b/test/instrumentation/res/values-or/strings.xml new file mode 100644 index 000000000..fe237acc9 --- /dev/null +++ b/test/instrumentation/res/values-or/strings.xml @@ -0,0 +1,20 @@ + + + + + "ଅନୁମତି ନିୟନ୍ତ୍ରକ ଟେଷ୍ଟ" + diff --git a/test/instrumentation/res/values-pa/strings.xml b/test/instrumentation/res/values-pa/strings.xml new file mode 100644 index 000000000..6b296145e --- /dev/null +++ b/test/instrumentation/res/values-pa/strings.xml @@ -0,0 +1,20 @@ + + + + + "ਇਜਾਜ਼ਤ ਕੰਟਰੋਲਰ ਸੰਬੰਧੀ ਜਾਂਚਾਂ" + diff --git a/test/instrumentation/res/values-pl/strings.xml b/test/instrumentation/res/values-pl/strings.xml new file mode 100644 index 000000000..8b7d198e9 --- /dev/null +++ b/test/instrumentation/res/values-pl/strings.xml @@ -0,0 +1,20 @@ + + + + + "Testy kontrolera uprawnień" + diff --git a/test/instrumentation/res/values-pt-rBR/strings.xml b/test/instrumentation/res/values-pt-rBR/strings.xml new file mode 100644 index 000000000..5463ded2b --- /dev/null +++ b/test/instrumentation/res/values-pt-rBR/strings.xml @@ -0,0 +1,20 @@ + + + + + "Testes do controlador de permissões" + diff --git a/test/instrumentation/res/values-pt-rPT/strings.xml b/test/instrumentation/res/values-pt-rPT/strings.xml new file mode 100644 index 000000000..b94172267 --- /dev/null +++ b/test/instrumentation/res/values-pt-rPT/strings.xml @@ -0,0 +1,20 @@ + + + + + "Testes de controladores de autorizações" + diff --git a/test/instrumentation/res/values-pt/strings.xml b/test/instrumentation/res/values-pt/strings.xml new file mode 100644 index 000000000..5463ded2b --- /dev/null +++ b/test/instrumentation/res/values-pt/strings.xml @@ -0,0 +1,20 @@ + + + + + "Testes do controlador de permissões" + diff --git a/test/instrumentation/res/values-ro/strings.xml b/test/instrumentation/res/values-ro/strings.xml new file mode 100644 index 000000000..344d7f47f --- /dev/null +++ b/test/instrumentation/res/values-ro/strings.xml @@ -0,0 +1,20 @@ + + + + + "Teste pentru controlerul de permisiuni" + diff --git a/test/instrumentation/res/values-ru/strings.xml b/test/instrumentation/res/values-ru/strings.xml new file mode 100644 index 000000000..f091f0a3d --- /dev/null +++ b/test/instrumentation/res/values-ru/strings.xml @@ -0,0 +1,20 @@ + + + + + "Тесты контролера разрешений" + diff --git a/test/instrumentation/res/values-si/strings.xml b/test/instrumentation/res/values-si/strings.xml new file mode 100644 index 000000000..bf1ec7251 --- /dev/null +++ b/test/instrumentation/res/values-si/strings.xml @@ -0,0 +1,20 @@ + + + + + "අවසර පාලක පරීක්ෂණ" + diff --git a/test/instrumentation/res/values-sk/strings.xml b/test/instrumentation/res/values-sk/strings.xml new file mode 100644 index 000000000..5300a6bab --- /dev/null +++ b/test/instrumentation/res/values-sk/strings.xml @@ -0,0 +1,20 @@ + + + + + "Testy ovládača povolení" + diff --git a/test/instrumentation/res/values-sl/strings.xml b/test/instrumentation/res/values-sl/strings.xml new file mode 100644 index 000000000..8fafbdd9b --- /dev/null +++ b/test/instrumentation/res/values-sl/strings.xml @@ -0,0 +1,20 @@ + + + + + "Preizkusi upravljalnika dovoljenj" + diff --git a/test/instrumentation/res/values-sq/strings.xml b/test/instrumentation/res/values-sq/strings.xml new file mode 100644 index 000000000..bfa79aa49 --- /dev/null +++ b/test/instrumentation/res/values-sq/strings.xml @@ -0,0 +1,20 @@ + + + + + "Testet e \"Kontrolluesit të autorizimeve\"" + diff --git a/test/instrumentation/res/values-sr/strings.xml b/test/instrumentation/res/values-sr/strings.xml new file mode 100644 index 000000000..c2a4a70c2 --- /dev/null +++ b/test/instrumentation/res/values-sr/strings.xml @@ -0,0 +1,20 @@ + + + + + "Тестирања контролера дозвола" + diff --git a/test/instrumentation/res/values-sv/strings.xml b/test/instrumentation/res/values-sv/strings.xml new file mode 100644 index 000000000..facf82d4b --- /dev/null +++ b/test/instrumentation/res/values-sv/strings.xml @@ -0,0 +1,20 @@ + + + + + "Test av behörighetskontroll" + diff --git a/test/instrumentation/res/values-sw/strings.xml b/test/instrumentation/res/values-sw/strings.xml new file mode 100644 index 000000000..cfe8e9d14 --- /dev/null +++ b/test/instrumentation/res/values-sw/strings.xml @@ -0,0 +1,20 @@ + + + + + "Majaribio ya Kidhibiti cha Ruhusa" + diff --git a/test/instrumentation/res/values-ta/strings.xml b/test/instrumentation/res/values-ta/strings.xml new file mode 100644 index 000000000..8ed526400 --- /dev/null +++ b/test/instrumentation/res/values-ta/strings.xml @@ -0,0 +1,20 @@ + + + + + "Permission Controller Tests" + diff --git a/test/instrumentation/res/values-te/strings.xml b/test/instrumentation/res/values-te/strings.xml new file mode 100644 index 000000000..333d454bf --- /dev/null +++ b/test/instrumentation/res/values-te/strings.xml @@ -0,0 +1,20 @@ + + + + + "అనుమతి నియంత్రణ పరీక్షలు" + diff --git a/test/instrumentation/res/values-th/strings.xml b/test/instrumentation/res/values-th/strings.xml new file mode 100644 index 000000000..273d876b0 --- /dev/null +++ b/test/instrumentation/res/values-th/strings.xml @@ -0,0 +1,20 @@ + + + + + "การทดสอบตัวควบคุมสิทธิ์" + diff --git a/test/instrumentation/res/values-tl/strings.xml b/test/instrumentation/res/values-tl/strings.xml new file mode 100644 index 000000000..73f6b48b2 --- /dev/null +++ b/test/instrumentation/res/values-tl/strings.xml @@ -0,0 +1,20 @@ + + + + + "Mga Pagsubok sa Controller ng Pahintulot" + diff --git a/test/instrumentation/res/values-tr/strings.xml b/test/instrumentation/res/values-tr/strings.xml new file mode 100644 index 000000000..fb0003aca --- /dev/null +++ b/test/instrumentation/res/values-tr/strings.xml @@ -0,0 +1,20 @@ + + + + + "İzin Denetleyici Testleri" + diff --git a/test/instrumentation/res/values-uk/strings.xml b/test/instrumentation/res/values-uk/strings.xml new file mode 100644 index 000000000..a9eaee948 --- /dev/null +++ b/test/instrumentation/res/values-uk/strings.xml @@ -0,0 +1,20 @@ + + + + + "Перевірка контролерів дозволів" + diff --git a/test/instrumentation/res/values-ur/strings.xml b/test/instrumentation/res/values-ur/strings.xml new file mode 100644 index 000000000..a43969175 --- /dev/null +++ b/test/instrumentation/res/values-ur/strings.xml @@ -0,0 +1,20 @@ + + + + + "اجازت کنٹرولر ٹیسٹس" + diff --git a/test/instrumentation/res/values-uz/strings.xml b/test/instrumentation/res/values-uz/strings.xml new file mode 100644 index 000000000..b27f688c8 --- /dev/null +++ b/test/instrumentation/res/values-uz/strings.xml @@ -0,0 +1,20 @@ + + + + + "Ruxsatlar kontrolleri sinovlari" + diff --git a/test/instrumentation/res/values-vi/strings.xml b/test/instrumentation/res/values-vi/strings.xml new file mode 100644 index 000000000..4037eaaff --- /dev/null +++ b/test/instrumentation/res/values-vi/strings.xml @@ -0,0 +1,20 @@ + + + + + "Thử nghiệm bộ kiểm soát quyền" + diff --git a/test/instrumentation/res/values-zh-rCN/strings.xml b/test/instrumentation/res/values-zh-rCN/strings.xml new file mode 100644 index 000000000..64c51e5f6 --- /dev/null +++ b/test/instrumentation/res/values-zh-rCN/strings.xml @@ -0,0 +1,20 @@ + + + + + "权限控制器测试" + diff --git a/test/instrumentation/res/values-zh-rHK/strings.xml b/test/instrumentation/res/values-zh-rHK/strings.xml new file mode 100644 index 000000000..bdc92ea0a --- /dev/null +++ b/test/instrumentation/res/values-zh-rHK/strings.xml @@ -0,0 +1,20 @@ + + + + + "權限控制器測試" + diff --git a/test/instrumentation/res/values-zh-rTW/strings.xml b/test/instrumentation/res/values-zh-rTW/strings.xml new file mode 100644 index 000000000..bdc92ea0a --- /dev/null +++ b/test/instrumentation/res/values-zh-rTW/strings.xml @@ -0,0 +1,20 @@ + + + + + "權限控制器測試" + diff --git a/test/instrumentation/res/values-zu/strings.xml b/test/instrumentation/res/values-zu/strings.xml new file mode 100644 index 000000000..37d32a616 --- /dev/null +++ b/test/instrumentation/res/values-zu/strings.xml @@ -0,0 +1,20 @@ + + + + + "Ukuhlolwa kwesilawuli semvume" + -- GitLab From 9019ff2d6008b20b4c036f7459e68a6e9ddfd455 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Wed, 6 Feb 2019 15:58:30 -0800 Subject: [PATCH 354/701] Add a dialog showing the enabled accessibility services. It shows the enabled accessibility services and their last access time. If there's only one such service we show a slightly different dialog. Bug: 123595964 Test: View dialog with one and two enabled services. Change-Id: I37a74880ebd99184c51a88a3dbc4740e8691138c --- AndroidManifest.xml | 9 ++ res/layout/accessibility_service_dialog.xml | 92 +++++++++++ .../accessibility_service_dialog_item.xml | 65 ++++++++ res/values/dimens.xml | 5 + res/values/strings.xml | 15 ++ .../ReviewAccessibilityServicesActivity.java | 152 ++++++++++++++++++ .../permission/utils/Utils.java | 19 ++- 7 files changed, 354 insertions(+), 3 deletions(-) create mode 100644 res/layout/accessibility_service_dialog.xml create mode 100644 res/layout/accessibility_service_dialog_item.xml create mode 100644 src/com/android/packageinstaller/permission/ui/ReviewAccessibilityServicesActivity.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index e520a778c..60358f2eb 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -128,6 +128,15 @@ android:excludeFromRecents="true" android:theme="@android:style/Theme.DeviceDefault.Light.Dialog.NoActionBar" /> + + + + + + + diff --git a/res/layout/accessibility_service_dialog.xml b/res/layout/accessibility_service_dialog.xml new file mode 100644 index 000000000..39f8807b0 --- /dev/null +++ b/res/layout/accessibility_service_dialog.xml @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/layout/accessibility_service_dialog_item.xml b/res/layout/accessibility_service_dialog_item.xml new file mode 100644 index 000000000..c36ad86c8 --- /dev/null +++ b/res/layout/accessibility_service_dialog_item.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 6dad90a4b..1afc2c95f 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -56,4 +56,9 @@ 16dp + 24dp + 18dp + 32dp + 16dp + diff --git a/res/values/strings.xml b/res/values/strings.xml index dba59c058..ffc0252c8 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -470,6 +470,21 @@ Force stop + + Settings + + + %s has full access to your device + + + %s accessibility services have full access to your device + + + %s can view your screen, actions, and inputs, perform actions, and control the display. + + + These services can view your screen, actions, and inputs, perform actions, and control the display. + Default apps diff --git a/src/com/android/packageinstaller/permission/ui/ReviewAccessibilityServicesActivity.java b/src/com/android/packageinstaller/permission/ui/ReviewAccessibilityServicesActivity.java new file mode 100644 index 000000000..c920cf379 --- /dev/null +++ b/src/com/android/packageinstaller/permission/ui/ReviewAccessibilityServicesActivity.java @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2019 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.packageinstaller.permission.ui; + +import android.accessibilityservice.AccessibilityServiceInfo; +import android.app.AlertDialog; +import android.app.AppOpsManager; +import android.content.Intent; +import android.content.pm.ApplicationInfo; +import android.content.pm.ResolveInfo; +import android.os.Bundle; +import android.provider.Settings; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.accessibility.AccessibilityManager; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.core.text.BidiFormatter; +import androidx.fragment.app.FragmentActivity; + +import com.android.packageinstaller.permission.utils.Utils; +import com.android.permissioncontroller.R; + +import java.util.List; + +/** + * A dialog listing the currently enabled accessibility services and their last access times. + */ +public final class ReviewAccessibilityServicesActivity extends FragmentActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + new AlertDialog.Builder(this) + .setView(createDialogView()) + .setPositiveButton(R.string.ok, null) + .setNeutralButton(R.string.settings, (dialog, which) -> + startActivity(new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS))) + .setOnDismissListener((dialog) -> finish()) + .show(); + } + + private @NonNull View createDialogView() { + AccessibilityManager accessibilityManager = getSystemService( + AccessibilityManager.class); + List services = accessibilityManager + .getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_ALL_MASK); + AppOpsManager appOpsManager = getSystemService(AppOpsManager.class); + + LayoutInflater layoutInflater = LayoutInflater.from(this); + View view = layoutInflater.inflate(R.layout.accessibility_service_dialog, null); + + int numServices = services.size(); + for (int i = 0; i < numServices; i++) { + ResolveInfo resolveInfo = services.get(i).getResolveInfo(); + ApplicationInfo appInfo = resolveInfo.serviceInfo.applicationInfo; + CharSequence label = getLabel(resolveInfo); + long lastAccessTime = getLastAccessTime(appInfo, appOpsManager); + + if (numServices == 1) { + // If there is only one enabled service, the dialog has its icon as a header. + + ((TextView) view.requireViewById(R.id.title)).setText( + getString(R.string.accessibility_service_dialog_title_single, label)); + ((TextView) view.requireViewById(R.id.bottom_text)).setText( + getString(R.string.accessibility_service_dialog_bottom_text_single, label)); + + ImageView headerIcon = view.requireViewById(R.id.header_icon); + headerIcon.setImageDrawable(Utils.getBadgedIcon(this, appInfo)); + headerIcon.setVisibility(View.VISIBLE); + + if (lastAccessTime != 0) { + TextView middleText = view.requireViewById(R.id.middle_text); + middleText.setText(getString(R.string.app_permission_most_recent_summary, + Utils.getAbsoluteTimeString(this, lastAccessTime))); + middleText.setVisibility(View.VISIBLE); + } + } else { + // Add an entry for each enabled service. + + ((TextView) view.requireViewById(R.id.title)).setText( + getString(R.string.accessibility_service_dialog_title_multiple, + services.size())); + ((TextView) view.requireViewById(R.id.bottom_text)).setText( + getString(R.string.accessibility_service_dialog_bottom_text_multiple)); + + ViewGroup servicesListView = view.requireViewById(R.id.items_container); + View itemView = layoutInflater.inflate(R.layout.accessibility_service_dialog_item, + servicesListView, false); + + ((TextView) itemView.requireViewById(R.id.title)).setText(label); + ((ImageView) itemView.requireViewById(R.id.icon)).setImageDrawable( + Utils.getBadgedIcon(this, appInfo)); + + if (lastAccessTime == 0) { + itemView.requireViewById(R.id.summary).setVisibility(View.GONE); + } else { + ((TextView) itemView.requireViewById(R.id.summary)).setText( + getString(R.string.app_permission_most_recent_summary, + Utils.getAbsoluteTimeString(this, lastAccessTime))); + } + + servicesListView.addView(itemView); + } + } + + return view; + } + + private @NonNull CharSequence getLabel(@NonNull ResolveInfo resolveInfo) { + return BidiFormatter.getInstance().unicodeWrap( + TextUtils.makeSafeForPresentation( + resolveInfo.loadLabel(getPackageManager()).toString(), 0, 0, + TextUtils.SAFE_STRING_FLAG_TRIM | TextUtils.SAFE_STRING_FLAG_FIRST_LINE)); + } + + private static long getLastAccessTime(@NonNull ApplicationInfo appInfo, + @NonNull AppOpsManager appOpsManager) { + List ops = appOpsManager.getOpsForPackage(appInfo.uid, + appInfo.packageName, AppOpsManager.OPSTR_ACCESS_ACCESSIBILITY); + long lastAccessTime = 0; + int numPkgOps = ops.size(); + for (int pkgOpNum = 0; pkgOpNum < numPkgOps; pkgOpNum++) { + AppOpsManager.PackageOps pkgOp = ops.get(pkgOpNum); + int numOps = pkgOp.getOps().size(); + for (int opNum = 0; opNum < numOps; opNum++) { + AppOpsManager.OpEntry op = pkgOp.getOps().get(opNum); + lastAccessTime = Math.max(lastAccessTime, op.getLastAccessTime()); + } + } + return lastAccessTime; + } +} diff --git a/src/com/android/packageinstaller/permission/utils/Utils.java b/src/com/android/packageinstaller/permission/utils/Utils.java index ab77457db..2fa9d1503 100644 --- a/src/com/android/packageinstaller/permission/utils/Utils.java +++ b/src/com/android/packageinstaller/permission/utils/Utils.java @@ -546,14 +546,27 @@ public final class Utils { if (groupUsage == null) { return null; } - long lastAccessTime = groupUsage.getLastAccessTime(); + return getAbsoluteTimeString(context, groupUsage.getLastAccessTime()); + } + + /** + * Build a string representing the given time if it happened on the current day and the date + * otherwise. + * + * @param context the context. + * @param lastAccessTime the time in milliseconds. + * + * @return a string representing the time or date of the given time or null if the time is 0. + */ + public static @Nullable String getAbsoluteTimeString(@NonNull Context context, + long lastAccessTime) { if (lastAccessTime == 0) { return null; } if (isToday(lastAccessTime)) { - return DateFormat.getTimeFormat(context).format(groupUsage.getLastAccessTime()); + return DateFormat.getTimeFormat(context).format(lastAccessTime); } else { - return DateFormat.getMediumDateFormat(context).format(groupUsage.getLastAccessTime()); + return DateFormat.getMediumDateFormat(context).format(lastAccessTime); } } -- GitLab From 23a1aa2a4fe10c781531041dc8fb0abb6f89385a Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Mon, 11 Feb 2019 11:09:21 -0800 Subject: [PATCH 355/701] Remove InCallService requirement for dialer role. Historically we didn't require dialer to implement InCallService. Bug: 124238689 Test: manual Change-Id: If632cc4d4537d4a735d6124b0628e7db2892c2b6 --- res/xml/roles.xml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/res/xml/roles.xml b/res/xml/roles.xml index 58715d421..2dd08de3d 100644 --- a/res/xml/roles.xml +++ b/res/xml/roles.xml @@ -135,16 +135,6 @@ - - - - - - - -- GitLab From bf776efccb84767b61252f6251b24b195536c98d Mon Sep 17 00:00:00 2001 From: Eugene Susla Date: Mon, 11 Feb 2019 15:39:28 -0800 Subject: [PATCH 356/701] Fix null system default dialer Fixes: 123637623 Test: ensure attached bug is fixed Change-Id: I833f662167a849bd4f34e2a5b780f49a0974145e --- .../packageinstaller/role/model/DialerRoleBehavior.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/com/android/packageinstaller/role/model/DialerRoleBehavior.java b/src/com/android/packageinstaller/role/model/DialerRoleBehavior.java index 556da0dd0..3a87c18af 100644 --- a/src/com/android/packageinstaller/role/model/DialerRoleBehavior.java +++ b/src/com/android/packageinstaller/role/model/DialerRoleBehavior.java @@ -23,6 +23,8 @@ import android.telephony.TelephonyManager; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import java.util.List; + /** * Class for behavior of the dialer role. * @@ -46,4 +48,10 @@ public class DialerRoleBehavior implements RoleBehavior { return EncryptionUnawareConfirmationMixin.getConfirmationMessage(role, packageName, context); } + + @NonNull + @Override + public List getDefaultHolders(@NonNull Role role, @NonNull Context context) { + return ExclusiveDefaultHolderMixin.getDefaultHolders(role, "config_defaultDialer", context); + } } -- GitLab From a13efa06bcbf143c68ba3379318693585348c2c5 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Tue, 12 Feb 2019 10:36:54 -0800 Subject: [PATCH 357/701] Optimize Permissions Hub and App Permissions screens. The majority of the time spent loading the Permissions Hub was spent loading the labels and icons for all apps. However, the screen does not show most apps, as they either have no uses or are system (which are not shown by default). This commit makes us only load labels and icons for apps we will show. We do the same thing for App Permissions, as it has the same issue. On my dev device, loading both Permissions Hub and App Permissions takes less than half the time it used to. Bug: 124052170 Test: Open Permissions Hub, change filters, select items and go back Test: Open App Permissions Screen. Change-Id: Ifd5d2b157793e6f277e185e0c3055e8f07f3f0d7 --- .../permission/model/PermissionApps.java | 59 ++++++++++++++--- .../permission/model/PermissionGroups.java | 32 ++++----- .../handheld/ManagePermissionsFragment.java | 3 +- .../ManageStandardPermissionsFragment.java | 55 +++++++++------- .../ui/handheld/PermissionUsageFragment.java | 66 +++++++++++-------- 5 files changed, 139 insertions(+), 76 deletions(-) diff --git a/src/com/android/packageinstaller/permission/model/PermissionApps.java b/src/com/android/packageinstaller/permission/model/PermissionApps.java index 1b5cff2a8..5d94045ee 100644 --- a/src/com/android/packageinstaller/permission/model/PermissionApps.java +++ b/src/com/android/packageinstaller/permission/model/PermissionApps.java @@ -253,7 +253,8 @@ public class PermissionApps { Pair appData = null; if (mAppDataCache != null && !mSkipUi) { - appData = mAppDataCache.getAppData(user.getIdentifier(), app); + appData = mAppDataCache.getAppData(user.getIdentifier(), + app.applicationInfo); } String label; @@ -326,8 +327,8 @@ public class PermissionApps { public static class PermissionApp implements Comparable { private final String mPackageName; private final AppPermissionGroup mAppPermissionGroup; - private final String mLabel; - private final Drawable mIcon; + private String mLabel; + private Drawable mIcon; private final ApplicationInfo mInfo; public PermissionApp(String packageName, AppPermissionGroup appPermissionGroup, @@ -395,6 +396,19 @@ public class PermissionApps { return mAppPermissionGroup; } + /** + * Load this app's label and icon if they were not previously loaded. + * + * @param appDataCache the cache of already-loaded labels and icons. + */ + public void loadLabelAndIcon(@NonNull AppDataCache appDataCache) { + if (mInfo.packageName.equals(mLabel) || mIcon == null) { + Pair appData = appDataCache.getAppData(getUid(), mInfo); + mLabel = appData.first; + mIcon = appData.second; + } + } + @Override public int compareTo(PermissionApp another) { final int result = mLabel.compareTo(another.mLabel); @@ -475,17 +489,17 @@ public class PermissionApps { * @return a pair of the label and icon. */ public @NonNull Pair getAppData(int userId, - @NonNull PackageInfo app) { + @NonNull ApplicationInfo app) { ArrayMap> dataForUser = mCache.get(userId); if (dataForUser == null) { dataForUser = new ArrayMap<>(); mCache.put(userId, dataForUser); } - Pair data = dataForUser.get(app.applicationInfo.packageName); + Pair data = dataForUser.get(app.packageName); if (data == null) { - data = Pair.create(app.applicationInfo.loadLabel(mPm).toString(), - Utils.getBadgedIcon(mContext, app.applicationInfo)); - dataForUser.put(app.applicationInfo.packageName, data); + data = Pair.create(app.loadLabel(mPm).toString(), + Utils.getBadgedIcon(mContext, app)); + dataForUser.put(app.packageName, data); } return data; } @@ -494,4 +508,33 @@ public class PermissionApps { public interface Callback { void onPermissionsLoaded(PermissionApps permissionApps); } + + /** + * Class used to asyncronously load apps' labels and icons. + */ + public static class AppDataLoader extends AsyncTask { + + private final Context mContext; + private final Runnable mCallback; + + public AppDataLoader(Context context, Runnable callback) { + mContext = context; + mCallback = callback; + } + + @Override + protected Void doInBackground(PermissionApp... args) { + AppDataCache appDataCache = new AppDataCache(mContext.getPackageManager(), mContext); + int numArgs = args.length; + for (int i = 0; i < numArgs; i++) { + args[i].loadLabelAndIcon(appDataCache); + } + return null; + } + + @Override + protected void onPostExecute(Void result) { + mCallback.run(); + } + } } diff --git a/src/com/android/packageinstaller/permission/model/PermissionGroups.java b/src/com/android/packageinstaller/permission/model/PermissionGroups.java index 446c85521..3da6cafac 100644 --- a/src/com/android/packageinstaller/permission/model/PermissionGroups.java +++ b/src/com/android/packageinstaller/permission/model/PermissionGroups.java @@ -54,17 +54,17 @@ public final class PermissionGroups implements LoaderCallbacks mGroups = new ArrayList<>(); private final Context mContext; private final PermissionsGroupsChangeCallback mCallback; - private final boolean mGetUiInfo; + private final boolean mGetAppUiInfo; public interface PermissionsGroupsChangeCallback { public void onPermissionGroupsChanged(); } public PermissionGroups(Context context, LoaderManager loaderManager, - PermissionsGroupsChangeCallback callback, boolean getUiInfo) { + PermissionsGroupsChangeCallback callback, boolean getAppUiInfo) { mContext = context; mCallback = callback; - mGetUiInfo = getUiInfo; + mGetAppUiInfo = getAppUiInfo; // Don't update immediately as otherwise we can get a callback before this object is // initialized. @@ -73,7 +73,7 @@ public final class PermissionGroups implements LoaderCallbacks> onCreateLoader(int id, Bundle args) { - return new PermissionsLoader(mContext, mGetUiInfo); + return new PermissionsLoader(mContext, mGetAppUiInfo); } @Override @@ -134,13 +134,13 @@ public final class PermissionGroups implements LoaderCallbacks getAllPermissionGroups(@NonNull Context context, - @Nullable Supplier isCanceled, boolean getUiInfo) { - return getPermissionGroups(context, isCanceled, getUiInfo, null, null); + @Nullable Supplier isCanceled, boolean getAppUiInfo) { + return getPermissionGroups(context, isCanceled, getAppUiInfo, null, null); } /** @@ -148,15 +148,15 @@ public final class PermissionGroups implements LoaderCallbacks getPermissionGroups(@NonNull Context context, - @Nullable Supplier isCanceled, boolean getUiInfo, @Nullable String groupName, - @Nullable String packageName) { + @Nullable Supplier isCanceled, boolean getAppUiInfo, + @Nullable String groupName, @Nullable String packageName) { ArraySet launcherPkgs = Utils.getLauncherPackages(context); PermissionApps.PmCache pmCache = new PermissionApps.PmCache( context.getPackageManager()); @@ -205,7 +205,7 @@ public final class PermissionGroups implements LoaderCallbacks> implements PackageManager.OnPermissionsChangedListener { - private final boolean mGetUiInfo; + private final boolean mGetAppUiInfo; - PermissionsLoader(Context context, boolean getUiInfo) { + PermissionsLoader(Context context, boolean getAppUiInfo) { super(context); - mGetUiInfo = getUiInfo; + mGetAppUiInfo = getAppUiInfo; } @Override @@ -323,7 +323,7 @@ public final class PermissionGroups implements LoaderCallbacks loadInBackground() { return getAllPermissionGroups(getContext(), this::isLoadInBackgroundCanceled, - mGetUiInfo); + mGetAppUiInfo); } @Override diff --git a/src/com/android/packageinstaller/permission/ui/handheld/ManagePermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/ManagePermissionsFragment.java index 5063983c5..307312479 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/ManagePermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/ManagePermissionsFragment.java @@ -58,8 +58,9 @@ abstract class ManagePermissionsFragment extends PermissionsFrameFragment if (ab != null) { ab.setDisplayHomeAsUpEnabled(true); } + mPermissions = new PermissionGroups(getContext(), getActivity().getLoaderManager(), this, - true); + false); mCollator = Collator.getInstance( getContext().getResources().getConfiguration().getLocales().get(0)); } diff --git a/src/com/android/packageinstaller/permission/ui/handheld/ManageStandardPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/ManageStandardPermissionsFragment.java index e81a31c0c..7e70b8cf7 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/ManageStandardPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/ManageStandardPermissionsFragment.java @@ -35,6 +35,7 @@ import androidx.preference.PreferenceScreen; import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.model.AppPermissionUsage; import com.android.packageinstaller.permission.model.AppPermissionUsage.GroupUsage; +import com.android.packageinstaller.permission.model.PermissionApps; import com.android.packageinstaller.permission.model.PermissionApps.PermissionApp; import com.android.packageinstaller.permission.model.PermissionGroup; import com.android.packageinstaller.permission.model.PermissionUsages; @@ -108,7 +109,7 @@ public final class ManageStandardPermissionsFragment extends ManagePermissionsFr Long.MAX_VALUE, PermissionUsages.USAGE_FLAG_LAST | PermissionUsages.USAGE_FLAG_HISTORICAL, getActivity().getLoaderManager(), - true, this::updateRecentlyUsedWidget, false); + false, this::updateRecentlyUsedWidget, false); return root; } @@ -219,30 +220,38 @@ public final class ManageStandardPermissionsFragment extends ManagePermissionsFr return; } - // Show the most recent three usages. int numAppsToShow = Math.min(usages.size(), MAXIMUM_APP_COUNT); - int i = 0; - for (; i < numAppsToShow; i++) { - Pair info = usages.get(i); - AppPermissionGroup group = info.second.getGroup(); - AppEntityInfo appEntityInfo = new AppEntityInfo.Builder() - .setIcon(info.first.getIcon()) - .setTitle(info.first.getLabel()) - .setSummary(group.getLabel()) - .setOnClickListener(v -> { - Intent intent = new Intent(context, AppPermissionActivity.class); - intent.putExtra(Intent.EXTRA_PACKAGE_NAME, group.getApp().packageName); - intent.putExtra(Intent.EXTRA_PERMISSION_NAME, group.getName()); - intent.putExtra(Intent.EXTRA_USER, group.getUser()); - context.startActivity(intent); - }) - .build(); - mAppUsageController.setAppEntity(i, appEntityInfo); - } - for (; i < MAXIMUM_APP_COUNT; i++) { - mAppUsageController.removeAppEntity(i); + + PermissionApps.PermissionApp[] permApps = new PermissionApps.PermissionApp[numAppsToShow]; + for (int i = 0; i < numAppsToShow; i++) { + permApps[i] = usages.get(i).first; } - mAppUsageController.apply(); + + new PermissionApps.AppDataLoader(context, () -> { + // Show the most recent three usages. + int i = 0; + for (; i < numAppsToShow; i++) { + Pair info = usages.get(i); + AppPermissionGroup group = info.second.getGroup(); + AppEntityInfo appEntityInfo = new AppEntityInfo.Builder() + .setIcon(info.first.getIcon()) + .setTitle(info.first.getLabel()) + .setSummary(group.getLabel()) + .setOnClickListener(v -> { + Intent intent = new Intent(context, AppPermissionActivity.class); + intent.putExtra(Intent.EXTRA_PACKAGE_NAME, group.getApp().packageName); + intent.putExtra(Intent.EXTRA_PERMISSION_NAME, group.getName()); + intent.putExtra(Intent.EXTRA_USER, group.getUser()); + context.startActivity(intent); + }) + .build(); + mAppUsageController.setAppEntity(i, appEntityInfo); + } + for (; i < MAXIMUM_APP_COUNT; i++) { + mAppUsageController.removeAppEntity(i); + } + mAppUsageController.apply(); + }).execute(permApps); } private static int compareAccessTime(@NonNull GroupUsage x, @NonNull GroupUsage y) { diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java index aa844df50..b9f03b049 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java @@ -49,6 +49,8 @@ import androidx.preference.PreferenceScreen; import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.model.AppPermissionUsage; import com.android.packageinstaller.permission.model.AppPermissionUsage.GroupUsage; +import com.android.packageinstaller.permission.model.PermissionApps; +import com.android.packageinstaller.permission.model.PermissionApps.PermissionApp; import com.android.packageinstaller.permission.model.PermissionUsages; import com.android.packageinstaller.permission.ui.handheld.FilterSpinner.FilterSpinnerAdapter; import com.android.packageinstaller.permission.ui.handheld.FilterSpinner.SpinnerItem; @@ -337,7 +339,6 @@ public class PermissionUsageFragment extends SettingsWithButtonHeader implements } updateUI(); - setLoading(false, true); } @Override @@ -367,9 +368,11 @@ public class PermissionUsageFragment extends SettingsWithButtonHeader implements long startTime = (timeFilterItem == null ? 0 : (curTime - timeFilterItem.getTime())); List> usages = new ArrayList<>(); + ArrayList permApps = new ArrayList<>(); int numApps = appPermissionUsages.size(); for (int appNum = 0; appNum < numApps; appNum++) { AppPermissionUsage appUsage = appPermissionUsages.get(appNum); + boolean used = false; List appGroups = appUsage.getGroupUsages(); int numGroups = appGroups.size(); for (int groupNum = 0; groupNum < numGroups; groupNum++) { @@ -395,6 +398,10 @@ public class PermissionUsageFragment extends SettingsWithButtonHeader implements } usages.add(Pair.create(appUsage, appGroups.get(groupNum))); + used = true; + } + if (used) { + permApps.add(appUsage.getApp()); } } @@ -437,38 +444,41 @@ public class PermissionUsageFragment extends SettingsWithButtonHeader implements Log.w(LOG_TAG, "Unexpected sort option: " + sortOption); } - ExpandablePreferenceGroup parent = null; - AppPermissionUsage lastAppPermissionUsage = null; + usages.removeIf((Pair usage) -> mFilterGroup != null + && !mFilterGroup.equals(usage.second.getGroup().getName())); - final int numUsages = usages.size(); - for (int usageNum = 0; usageNum < numUsages; usageNum++) { - final Pair usage = usages.get(usageNum); - AppPermissionUsage appPermissionUsage = usage.first; - GroupUsage groupUsage = usage.second; + // If there are no entries, don't show anything. + if (permApps.isEmpty()) { + screen.removeAll(); + } - if (mFilterGroup != null && !mFilterGroup.equals(groupUsage.getGroup().getName())) { - continue; - } + new PermissionApps.AppDataLoader(context, () -> { + ExpandablePreferenceGroup parent = null; + AppPermissionUsage lastAppPermissionUsage = null; - String accessTimeString = Utils.getAbsoluteLastUsageString(context, groupUsage); + final int numUsages = usages.size(); + for (int usageNum = 0; usageNum < numUsages; usageNum++) { + final Pair usage = usages.get(usageNum); + AppPermissionUsage appPermissionUsage = usage.first; + GroupUsage groupUsage = usage.second; - if (lastAppPermissionUsage != appPermissionUsage) { - // Add a "parent" entry for the app that will expand to the individual entries. - parent = createExpandablePreferenceGroup(context, appPermissionUsage, - sortOption == SORT_RECENT ? accessTimeString : null); - category.addPreference(parent); - lastAppPermissionUsage = appPermissionUsage; - } + String accessTimeString = Utils.getAbsoluteLastUsageString(context, groupUsage); - parent.addPreference(createPermissionUsagePreference(context, appPermissionUsage, - groupUsage, accessTimeString)); - parent.addSummaryIcon(groupUsage.getGroup().getIconResId()); - } + if (lastAppPermissionUsage != appPermissionUsage) { + // Add a "parent" entry for the app that will expand to the individual entries. + parent = createExpandablePreferenceGroup(context, appPermissionUsage, + sortOption == SORT_RECENT ? accessTimeString : null); + category.addPreference(parent); + lastAppPermissionUsage = appPermissionUsage; + } - // If there are no entries, don't show anything. - if (parent == null) { - screen.removeAll(); - } + parent.addPreference(createPermissionUsagePreference(context, appPermissionUsage, + groupUsage, accessTimeString)); + parent.addSummaryIcon(groupUsage.getGroup().getIconResId()); + } + + setLoading(false, true); + }).execute(permApps.toArray(new PermissionApps.PermissionApp[permApps.size()])); } private TimeFilterItem getSelectedFilterItem() { @@ -502,7 +512,7 @@ public class PermissionUsageFragment extends SettingsWithButtonHeader implements mPermissionUsages.load(null /*filterPackageName*/, null /*filterPermissionGroup*/, filterTimeBeginMillis, Long.MAX_VALUE, PermissionUsages.USAGE_FLAG_LAST | PermissionUsages.USAGE_FLAG_HISTORICAL, getActivity().getLoaderManager(), - true /*getUiInfo*/, this /*callback*/, false /*sync*/); + false /*getUiInfo*/, this /*callback*/, false /*sync*/); } /** -- GitLab From 8302b126c80138d31e0db25e63d5e5709ae8e347 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Tue, 29 Jan 2019 13:15:06 -0800 Subject: [PATCH 358/701] Add a wifi-style progress bar to the Permissions Hub. Use a linear progress bar (like on the wifi scan screen) when the Permissions Hub is loading (except for the initial load, when we still show the circular icon). We hide the progress bar when it is not visible so we keep the new app bar shadow behavior. Bug: 123538370 Test: Open Permissions Hub, refresh it, click something, and go back. Change-Id: I1a9dc7d831e387bfd917d16feacb11cdc448d256 --- PermissionController.mk | 3 ++- res/layout/permissions_frame.xml | 9 ++++++--- .../ui/handheld/PermissionUsageFragment.java | 16 ++++++++++++++++ .../ui/handheld/PermissionsFrameFragment.java | 10 ++++++++++ 4 files changed, 34 insertions(+), 4 deletions(-) diff --git a/PermissionController.mk b/PermissionController.mk index 16ec98c72..86b5c79c9 100644 --- a/PermissionController.mk +++ b/PermissionController.mk @@ -35,7 +35,8 @@ LOCAL_STATIC_ANDROID_LIBRARIES += \ SettingsLibActionButtonsPreference \ SettingsLibBarChartPreference \ SettingsLibEntityHeaderWidgets \ - SettingsLibActionBarShadow + SettingsLibActionBarShadow \ + SettingsLibProgressBar LOCAL_STATIC_JAVA_LIBRARIES := \ androidx.annotation_annotation diff --git a/res/layout/permissions_frame.xml b/res/layout/permissions_frame.xml index 025835116..4f71becba 100644 --- a/res/layout/permissions_frame.xml +++ b/res/layout/permissions_frame.xml @@ -14,10 +14,13 @@ limitations under the License. --> - + android:layout_height="match_parent" + android:orientation="vertical"> + + - + diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java index b9f03b049..b2d162c55 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java @@ -102,6 +102,9 @@ public class PermissionUsageFragment extends SettingsWithButtonHeader implements private static final String KEY_SPINNER_SORT_INDEX = "_sort_index"; private static final String SPINNER_SORT_INDEX_KEY = PermissionUsageFragment.class.getName() + KEY_SPINNER_SORT_INDEX; + private static final String KEY_FINISHED_INITIAL_LOAD = "_finished_initial_load"; + private static final String FINISHED_INITIAL_LOAD_KEY = PermissionUsageFragment.class.getName() + + KEY_FINISHED_INITIAL_LOAD; /** * The maximum number of columns shown in the bar chart. @@ -125,6 +128,8 @@ public class PermissionUsageFragment extends SettingsWithButtonHeader implements private Spinner mSortSpinner; private FilterSpinnerAdapter mSortAdapter; + private boolean mFinishedInitialLoad; + /** * Only used to restore permission selection state or use the passed permission after onCreate. * Once the first list of groups is reported, this becomes invalid. @@ -162,6 +167,10 @@ public class PermissionUsageFragment extends SettingsWithButtonHeader implements public void onStart() { super.onStart(); getActivity().setTitle(R.string.permission_usage_title); + + if (mFinishedInitialLoad) { + setProgressBarVisible(true); + } } @Override @@ -173,6 +182,7 @@ public class PermissionUsageFragment extends SettingsWithButtonHeader implements mSavedGroupName = savedInstanceState.getString(PERMS_INDEX_KEY); mSavedTimeSpinnerIndex = savedInstanceState.getInt(SPINNER_TIME_INDEX_KEY); mSavedSortSpinnerIndex = savedInstanceState.getInt(SPINNER_SORT_INDEX_KEY); + mFinishedInitialLoad = savedInstanceState.getBoolean(FINISHED_INITIAL_LOAD_KEY); } setLoading(true, false); @@ -271,6 +281,7 @@ public class PermissionUsageFragment extends SettingsWithButtonHeader implements outState.putString(PERMS_INDEX_KEY, mFilterGroup); outState.putInt(SPINNER_TIME_INDEX_KEY, mFilterSpinnerTime.getSelectedItemPosition()); outState.putInt(SPINNER_SORT_INDEX_KEY, mSortSpinner.getSelectedItemPosition()); + outState.putBoolean(FINISHED_INITIAL_LOAD_KEY, mFinishedInitialLoad); } @Override @@ -478,6 +489,8 @@ public class PermissionUsageFragment extends SettingsWithButtonHeader implements } setLoading(false, true); + mFinishedInitialLoad = true; + setProgressBarVisible(false); }).execute(permApps.toArray(new PermissionApps.PermissionApp[permApps.size()])); } @@ -513,6 +526,9 @@ public class PermissionUsageFragment extends SettingsWithButtonHeader implements filterTimeBeginMillis, Long.MAX_VALUE, PermissionUsages.USAGE_FLAG_LAST | PermissionUsages.USAGE_FLAG_HISTORICAL, getActivity().getLoaderManager(), false /*getUiInfo*/, this /*callback*/, false /*sync*/); + if (mFinishedInitialLoad) { + setProgressBarVisible(true); + } } /** diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionsFrameFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionsFrameFragment.java index 295f183c1..4411f0d89 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionsFrameFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionsFrameFragment.java @@ -47,6 +47,8 @@ public abstract class PermissionsFrameFragment extends PreferenceFragmentCompat private TextView mEmptyView; private View mLoadingView; + private View mProgressHeader; + private View mProgressView; private ViewGroup mPrefsView; private NestedScrollView mNestedScrollView; private boolean mIsLoading; @@ -83,6 +85,9 @@ public abstract class PermissionsFrameFragment extends PreferenceFragmentCompat setLoading(mIsLoading, false, true /* force */); mPrefsView.addView(mPreferencesContainer, 0); mNestedScrollView = rootView.requireViewById(R.id.nested_scroll_view); + mProgressHeader = rootView.requireViewById(R.id.progress_bar_animation); + mProgressView = rootView.requireViewById(R.id.progress_bar_background); + setProgressBarVisible(false); return rootView; } @@ -125,6 +130,11 @@ public abstract class PermissionsFrameFragment extends PreferenceFragmentCompat } } + protected void setProgressBarVisible(boolean visible) { + mProgressHeader.setVisibility(visible ? View.VISIBLE : View.GONE); + mProgressView.setVisibility(visible ? View.VISIBLE : View.GONE); + } + /** * Either show the empty view or the recycler view. To be called any time the adapter changes. */ -- GitLab From f08cfd454565dd3d7bd3cc2f2fc2e6a99f0364da Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Tue, 12 Feb 2019 16:09:32 -0800 Subject: [PATCH 359/701] Add role behavior for home. So that we can disable home for work profile, exclude fallback home activities from Settings in UI, and indicate work profile support. Bug: 124260975 Test: manual Change-Id: I27d114f610de3730f576f7ea3deb497e33522ce5 --- res/values/strings.xml | 3 + res/xml/roles.xml | 6 +- .../role/model/AssistantRoleBehavior.java | 7 +- .../role/model/HomeRoleBehavior.java | 87 +++++++++++++++++++ .../packageinstaller/role/model/Role.java | 18 ++++ .../role/model/RoleBehavior.java | 10 +++ .../role/model/SmsRoleBehavior.java | 5 +- .../role/ui/DefaultAppFragment.java | 13 +-- .../role/utils/UserUtils.java | 13 +++ 9 files changed, 149 insertions(+), 13 deletions(-) create mode 100644 src/com/android/packageinstaller/role/model/HomeRoleBehavior.java diff --git a/res/values/strings.xml b/res/values/strings.xml index aba84ac9a..b3b348fc7 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -533,6 +533,9 @@ Car Projection app + + Doesn\u2019t support work profile + Note: If you restart your device and have a screen lock set, this app can\u2019t start until you unlock your device. diff --git a/res/xml/roles.xml b/res/xml/roles.xml index 344f86f29..eb685c3af 100644 --- a/res/xml/roles.xml +++ b/res/xml/roles.xml @@ -318,7 +318,11 @@ ~ @see com.android.settings.applications.defaultapps.DefaultHomePicker ~ @see com.android.server.pm.PackageManagerService#setHomeActivity(ComponentName, int) --> - + diff --git a/src/com/android/packageinstaller/role/model/AssistantRoleBehavior.java b/src/com/android/packageinstaller/role/model/AssistantRoleBehavior.java index 1d0e9ef07..797fc6f5e 100644 --- a/src/com/android/packageinstaller/role/model/AssistantRoleBehavior.java +++ b/src/com/android/packageinstaller/role/model/AssistantRoleBehavior.java @@ -28,7 +28,6 @@ import android.content.pm.ServiceInfo; import android.content.res.Resources; import android.content.res.XmlResourceParser; import android.os.UserHandle; -import android.os.UserManager; import android.provider.Settings; import android.service.voice.VoiceInteractionService; import android.util.ArraySet; @@ -38,6 +37,8 @@ import android.util.Xml; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import com.android.packageinstaller.role.utils.UserUtils; + import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; @@ -56,9 +57,7 @@ public class AssistantRoleBehavior implements RoleBehavior { @Override public boolean isAvailableAsUser(@NonNull Role role, @NonNull UserHandle user, @NonNull Context context) { - UserManager userManager = context.getSystemService(UserManager.class); - - return !userManager.isManagedProfile(user.getIdentifier()) + return !UserUtils.isWorkProfile(user, context) && !context.getSystemService(ActivityManager.class).isLowRamDevice(); } diff --git a/src/com/android/packageinstaller/role/model/HomeRoleBehavior.java b/src/com/android/packageinstaller/role/model/HomeRoleBehavior.java new file mode 100644 index 000000000..627d5f2a6 --- /dev/null +++ b/src/com/android/packageinstaller/role/model/HomeRoleBehavior.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2019 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.packageinstaller.role.model; + +import android.content.Context; +import android.content.Intent; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.os.Build; +import android.os.UserHandle; +import android.provider.Settings; + +import androidx.annotation.NonNull; +import androidx.preference.Preference; + +import com.android.packageinstaller.role.utils.UserUtils; +import com.android.permissioncontroller.R; + +import java.util.Objects; + +/** + * Class for behavior of the home role. + * + * @see com.android.settings.applications.DefaultAppSettings + * @see com.android.settings.applications.defaultapps.DefaultHomePreferenceController + * @see com.android.settings.applications.defaultapps.DefaultHomePicker + */ +public class HomeRoleBehavior implements RoleBehavior { + + @Override + public boolean isAvailableAsUser(@NonNull Role role, @NonNull UserHandle user, + @NonNull Context context) { + return !UserUtils.isWorkProfile(user, context); + } + + @Override + public void prepareApplicationPreferenceAsUser(@NonNull Role role, + @NonNull Preference preference, @NonNull ApplicationInfo applicationInfo, + @NonNull UserHandle user, @NonNull Context context) { + // Home is not available for work profile, so we can just use the current user. + boolean isSettingsApplication = isSettingsApplication(applicationInfo, context); + preference.setVisible(!isSettingsApplication); + boolean missingWorkProfileSupport = isMissingWorkProfileSupport(applicationInfo, context); + preference.setEnabled(!missingWorkProfileSupport); + preference.setSummary(missingWorkProfileSupport ? context.getString( + R.string.home_missing_work_profile_support) : null); + } + + private boolean isMissingWorkProfileSupport(@NonNull ApplicationInfo applicationInfo, + @NonNull Context context) { + boolean hasWorkProfile = UserUtils.getWorkProfile(context) != null; + if (!hasWorkProfile) { + return false; + } + boolean isWorkProfileSupported = applicationInfo.targetSdkVersion + >= Build.VERSION_CODES.LOLLIPOP; + return !isWorkProfileSupported; + } + + private boolean isSettingsApplication(@NonNull ApplicationInfo applicationInfo, + @NonNull Context context) { + PackageManager packageManager = context.getPackageManager(); + ResolveInfo resolveInfo = packageManager.resolveActivity(new Intent( + Settings.ACTION_SETTINGS), PackageManager.MATCH_DEFAULT_ONLY + | PackageManager.MATCH_DIRECT_BOOT_AWARE + | PackageManager.MATCH_DIRECT_BOOT_UNAWARE); + if (resolveInfo == null || resolveInfo.activityInfo == null) { + return false; + } + return Objects.equals(applicationInfo.packageName, resolveInfo.activityInfo.packageName); + } +} diff --git a/src/com/android/packageinstaller/role/model/Role.java b/src/com/android/packageinstaller/role/model/Role.java index e7b77e2d7..1ae8b1d15 100644 --- a/src/com/android/packageinstaller/role/model/Role.java +++ b/src/com/android/packageinstaller/role/model/Role.java @@ -31,6 +31,7 @@ import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.StringRes; +import androidx.preference.Preference; import com.android.packageinstaller.Constants; import com.android.packageinstaller.role.utils.PackageUtils; @@ -261,6 +262,23 @@ public class Role { return null; } + /** + * Prepare a {@link Preference} for an application. + * + * @param preference the {@link Preference} for the application + * @param applicationInfo the {@link ApplicationInfo} for the application + * @param user the user for the application + * @param context the {@code Context} to retrieve system services + */ + public void prepareApplicationPreferenceAsUser(@NonNull Preference preference, + @NonNull ApplicationInfo applicationInfo, @NonNull UserHandle user, + @NonNull Context context) { + if (mBehavior != null) { + mBehavior.prepareApplicationPreferenceAsUser(this, preference, applicationInfo, user, + context); + } + } + /** * Get the confirmation message for adding an application as a holder of this role. * diff --git a/src/com/android/packageinstaller/role/model/RoleBehavior.java b/src/com/android/packageinstaller/role/model/RoleBehavior.java index 7bdd90aad..d0f89c348 100644 --- a/src/com/android/packageinstaller/role/model/RoleBehavior.java +++ b/src/com/android/packageinstaller/role/model/RoleBehavior.java @@ -18,10 +18,12 @@ package com.android.packageinstaller.role.model; import android.content.Context; import android.content.Intent; +import android.content.pm.ApplicationInfo; import android.os.UserHandle; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.preference.Preference; import java.util.Collections; import java.util.List; @@ -64,6 +66,14 @@ public interface RoleBehavior { return null; } + /** + * @see Role#prepareApplicationPreferenceAsUser(Preference, ApplicationInfo, UserHandle, + * Context) + */ + default void prepareApplicationPreferenceAsUser(@NonNull Role role, + @NonNull Preference preference, @NonNull ApplicationInfo applicationInfo, + @NonNull UserHandle user, @NonNull Context context) {} + /** * @see Role#getConfirmationMessage(String, Context) */ diff --git a/src/com/android/packageinstaller/role/model/SmsRoleBehavior.java b/src/com/android/packageinstaller/role/model/SmsRoleBehavior.java index 0485e1c18..2f41f1b86 100644 --- a/src/com/android/packageinstaller/role/model/SmsRoleBehavior.java +++ b/src/com/android/packageinstaller/role/model/SmsRoleBehavior.java @@ -19,13 +19,13 @@ package com.android.packageinstaller.role.model; import android.content.Context; import android.os.Process; import android.os.UserHandle; -import android.os.UserManager; import android.telephony.TelephonyManager; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.packageinstaller.permission.utils.CollectionUtils; +import com.android.packageinstaller.role.utils.UserUtils; import java.util.List; @@ -41,8 +41,7 @@ public class SmsRoleBehavior implements RoleBehavior { @Override public boolean isAvailableAsUser(@NonNull Role role, @NonNull UserHandle user, @NonNull Context context) { - UserManager userManager = context.getSystemService(UserManager.class); - if (userManager.isManagedProfile(user.getIdentifier())) { + if (UserUtils.isWorkProfile(user, context)) { return false; } // FIXME: STOPSHIP: Add an appropriate @SystemApi for this. diff --git a/src/com/android/packageinstaller/role/ui/DefaultAppFragment.java b/src/com/android/packageinstaller/role/ui/DefaultAppFragment.java index f01de51d3..0aeaefdbb 100644 --- a/src/com/android/packageinstaller/role/ui/DefaultAppFragment.java +++ b/src/com/android/packageinstaller/role/ui/DefaultAppFragment.java @@ -136,8 +136,8 @@ public class DefaultAppFragment extends SettingsFragment Drawable icon = AppCompatResources.getDrawable(context, R.drawable.ic_remove_circle); String title = context.getString(R.string.default_app_none); boolean noHolderApplication = !hasHolderApplication(qualifyingApplications); - addPreference(PREFERENCE_KEY_NONE, icon, title, noHolderApplication, oldPreferences, - preferenceScreen, context); + addPreference(PREFERENCE_KEY_NONE, icon, title, noHolderApplication, null, + oldPreferences, preferenceScreen, context); } int qualifyingApplicationsSize = qualifyingApplications.size(); @@ -149,8 +149,8 @@ public class DefaultAppFragment extends SettingsFragment String key = qualifyingApplicationInfo.packageName; Drawable icon = Utils.getBadgedIcon(context, qualifyingApplicationInfo); String title = Utils.getAppLabel(qualifyingApplicationInfo, context); - addPreference(key, icon, title, isHolderApplication, oldPreferences, preferenceScreen, - context); + addPreference(key, icon, title, isHolderApplication, qualifyingApplicationInfo, + oldPreferences, preferenceScreen, context); } updateState(); @@ -171,7 +171,7 @@ public class DefaultAppFragment extends SettingsFragment } private void addPreference(@NonNull String key, @NonNull Drawable icon, - @NonNull CharSequence title, boolean checked, + @NonNull CharSequence title, boolean checked, @Nullable ApplicationInfo applicationInfo, @NonNull ArrayMap oldPreferences, @NonNull PreferenceScreen preferenceScreen, @NonNull Context context) { AppIconRadioButtonPreference preference = (AppIconRadioButtonPreference) oldPreferences.get( @@ -186,6 +186,9 @@ public class DefaultAppFragment extends SettingsFragment preference.setOnPreferenceClickListener(this); } preference.setChecked(checked); + if (applicationInfo != null) { + mRole.prepareApplicationPreferenceAsUser(preference, applicationInfo, mUser, context); + } // TODO: Ordering? preferenceScreen.addPreference(preference); } diff --git a/src/com/android/packageinstaller/role/utils/UserUtils.java b/src/com/android/packageinstaller/role/utils/UserUtils.java index c13487f98..2145a70e8 100644 --- a/src/com/android/packageinstaller/role/utils/UserUtils.java +++ b/src/com/android/packageinstaller/role/utils/UserUtils.java @@ -35,6 +35,19 @@ public class UserUtils { private UserUtils() {} + /** + * Check whether a user is a work profile. + * + * @param user the user to check + * @param context the {@code Context} to retrieve system services + * + * @return whether the user is a work profile + */ + public static boolean isWorkProfile(@NonNull UserHandle user, @NonNull Context context) { + UserManager userManager = context.getSystemService(UserManager.class); + return userManager.isManagedProfile(user.getIdentifier()); + } + /** * Get the work profile of current user, if any. * -- GitLab From f3a7883c630c779ea1663a0e4eba04237f45f9d8 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Wed, 13 Feb 2019 09:03:38 -0800 Subject: [PATCH 360/701] Always show the horizontal progress bar when updating Permissions Hub. This ensures we always show the new horizontal progress bar when updating the Permissions Hub UI. Previously we only did it when loading new data; this extends us to also show it when showing/hiding system apps or changing a group filter. On my dev device these happen very quickly, so it doesn't matter much, but if they are slower on other devices it's probably worth doing. Test: Reload Permissions Hub. Change-Id: Ib3d9d5e0b9196e17ee4f51fd4ff8459256d4e7a2 --- .../permission/ui/handheld/PermissionUsageFragment.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java index b2d162c55..7b960362a 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java @@ -363,6 +363,9 @@ public class PermissionUsageFragment extends SettingsWithButtonHeader implements if (appPermissionUsages.isEmpty() || getActivity() == null) { return; } + if (mFinishedInitialLoad) { + setProgressBarVisible(true); + } Context context = getActivity(); PreferenceScreen screen = getPreferenceScreen(); -- GitLab From 8435e4f463745941ae6362a425d1e686f1b71065 Mon Sep 17 00:00:00 2001 From: Evan Severson Date: Wed, 13 Feb 2019 13:10:19 -0800 Subject: [PATCH 361/701] Delete obsolete layouts Test: Build and open all permission screens Change-Id: Ic6ca78751ee2c820920ff51a9038fc0a95104728 --- res/layout/label.xml | 22 ---------------------- res/layout/permissions_list.xml | 31 ------------------------------- 2 files changed, 53 deletions(-) delete mode 100644 res/layout/label.xml delete mode 100644 res/layout/permissions_list.xml diff --git a/res/layout/label.xml b/res/layout/label.xml deleted file mode 100644 index e1a51434c..000000000 --- a/res/layout/label.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - diff --git a/res/layout/permissions_list.xml b/res/layout/permissions_list.xml deleted file mode 100644 index 5e3ae0f5c..000000000 --- a/res/layout/permissions_list.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - -- GitLab From 39b996ac50a2a4164032a35438900dd09e848a1c Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Wed, 13 Feb 2019 17:06:05 -0800 Subject: [PATCH 362/701] Sort roles and holders. This change uses Collator to sort the default apps, special app accesses and qualifying apps. Previously their order was hard coded in Settings preference XML, and arranged in (roughly) alphabetical order. Bug: 124401424 Test: manual Change-Id: I9f700f0bae2e8bee7569599a964c4ca2ca01b703 --- .../role/ui/DefaultAppListViewModel.java | 20 +++--- .../role/ui/DefaultAppViewModel.java | 13 +++- .../role/ui/RoleListSortFunction.java | 52 ++++++++++++++++ .../role/ui/RoleSortFunction.java | 62 +++++++++++++++++++ .../ui/SpecialAppAccessListViewModel.java | 7 ++- .../role/ui/SpecialAppAccessViewModel.java | 7 ++- 6 files changed, 147 insertions(+), 14 deletions(-) create mode 100644 src/com/android/packageinstaller/role/ui/RoleListSortFunction.java create mode 100644 src/com/android/packageinstaller/role/ui/RoleSortFunction.java diff --git a/src/com/android/packageinstaller/role/ui/DefaultAppListViewModel.java b/src/com/android/packageinstaller/role/ui/DefaultAppListViewModel.java index 4662900b6..ade0f1631 100644 --- a/src/com/android/packageinstaller/role/ui/DefaultAppListViewModel.java +++ b/src/com/android/packageinstaller/role/ui/DefaultAppListViewModel.java @@ -23,10 +23,14 @@ import android.os.UserHandle; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.lifecycle.AndroidViewModel; +import androidx.lifecycle.LiveData; +import androidx.lifecycle.Transformations; import androidx.lifecycle.ViewModel; import com.android.packageinstaller.role.utils.UserUtils; +import java.util.List; + /** * {@link ViewModel} for the list of default apps. */ @@ -35,20 +39,22 @@ public class DefaultAppListViewModel extends AndroidViewModel { @NonNull private final UserHandle mUser; @NonNull - private final RoleListLiveData mLiveData; + private final LiveData> mLiveData; @Nullable private final UserHandle mWorkProfile; @Nullable - private final RoleListLiveData mWorkLiveData; + private final LiveData> mWorkLiveData; public DefaultAppListViewModel(@NonNull Application application) { super(application); mUser = Process.myUserHandle(); - mLiveData = new RoleListLiveData(true, mUser, application); + RoleListSortFunction sortFunction = new RoleListSortFunction(application); + mLiveData = Transformations.map(new RoleListLiveData(true, mUser, application), + sortFunction); mWorkProfile = UserUtils.getWorkProfile(application); - mWorkLiveData = mWorkProfile != null ? new RoleListLiveData(true, mWorkProfile, application) - : null; + mWorkLiveData = mWorkProfile != null ? Transformations.map(new RoleListLiveData(true, + mWorkProfile, application), sortFunction) : null; } @NonNull @@ -57,7 +63,7 @@ public class DefaultAppListViewModel extends AndroidViewModel { } @NonNull - public RoleListLiveData getLiveData() { + public LiveData> getLiveData() { return mLiveData; } @@ -76,7 +82,7 @@ public class DefaultAppListViewModel extends AndroidViewModel { } @Nullable - public RoleListLiveData getWorkLiveData() { + public LiveData> getWorkLiveData() { return mWorkLiveData; } } diff --git a/src/com/android/packageinstaller/role/ui/DefaultAppViewModel.java b/src/com/android/packageinstaller/role/ui/DefaultAppViewModel.java index e18d7907e..390b76cae 100644 --- a/src/com/android/packageinstaller/role/ui/DefaultAppViewModel.java +++ b/src/com/android/packageinstaller/role/ui/DefaultAppViewModel.java @@ -17,22 +17,28 @@ package com.android.packageinstaller.role.ui; import android.app.Application; +import android.content.pm.ApplicationInfo; import android.os.UserHandle; +import android.util.Pair; import androidx.annotation.NonNull; import androidx.lifecycle.AndroidViewModel; +import androidx.lifecycle.LiveData; +import androidx.lifecycle.Transformations; import androidx.lifecycle.ViewModel; import androidx.lifecycle.ViewModelProvider; import com.android.packageinstaller.role.model.Role; +import java.util.List; + /** * {@link ViewModel} for a default app. */ public class DefaultAppViewModel extends AndroidViewModel { @NonNull - private final RoleLiveData mRoleLiveData; + private final LiveData>> mRoleLiveData; @NonNull private final ManageRoleHolderStateLiveData mManageRoleHolderStateLiveData = @@ -42,11 +48,12 @@ public class DefaultAppViewModel extends AndroidViewModel { @NonNull Application application) { super(application); - mRoleLiveData = new RoleLiveData(role, user, application); + mRoleLiveData = Transformations.map(new RoleLiveData(role, user, application), + new RoleSortFunction(application)); } @NonNull - public RoleLiveData getRoleLiveData() { + public LiveData>> getRoleLiveData() { return mRoleLiveData; } diff --git a/src/com/android/packageinstaller/role/ui/RoleListSortFunction.java b/src/com/android/packageinstaller/role/ui/RoleListSortFunction.java new file mode 100644 index 000000000..54c526dfb --- /dev/null +++ b/src/com/android/packageinstaller/role/ui/RoleListSortFunction.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2019 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.packageinstaller.role.ui; + +import android.content.Context; +import android.icu.text.Collator; + +import androidx.annotation.NonNull; +import androidx.arch.core.util.Function; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + +/** + * A function for {@link androidx.lifecycle.Transformations#map(androidx.lifecycle.LiveData, + * Function)} that sorts a live data for role list. + */ +public class RoleListSortFunction implements Function, List> { + + @NonNull + private final Comparator mComparator; + + public RoleListSortFunction(@NonNull Context context) { + Collator collator = Collator.getInstance(context.getResources().getConfiguration() + .getLocales().get(0)); + mComparator = Comparator.comparing(roleItem -> context.getString( + roleItem.getRole().getLabelResource()), collator); + } + + @NonNull + @Override + public List apply(@NonNull List input) { + List sorted = new ArrayList<>(input); + sorted.sort(mComparator); + return sorted; + } +} diff --git a/src/com/android/packageinstaller/role/ui/RoleSortFunction.java b/src/com/android/packageinstaller/role/ui/RoleSortFunction.java new file mode 100644 index 000000000..d3ebaa361 --- /dev/null +++ b/src/com/android/packageinstaller/role/ui/RoleSortFunction.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2019 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.packageinstaller.role.ui; + +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.icu.text.Collator; +import android.os.UserHandle; +import android.util.Pair; + +import androidx.annotation.NonNull; +import androidx.arch.core.util.Function; + +import com.android.packageinstaller.permission.utils.Utils; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + +/** + * A function for {@link androidx.lifecycle.Transformations#map(androidx.lifecycle.LiveData, + * Function)} that sorts a live data for role. + */ +public class RoleSortFunction implements Function>, + List>> { + + @NonNull + private final Comparator> mComparator; + + public RoleSortFunction(@NonNull Context context) { + Collator collator = Collator.getInstance(context.getResources().getConfiguration() + .getLocales().get(0)); + Comparator> labelComparator = Comparator.comparing(role -> + Utils.getAppLabel(role.first, context), collator); + Comparator> userIdComparator = Comparator.comparingInt(role + -> UserHandle.getUserHandleForUid(role.first.uid).getIdentifier()); + mComparator = labelComparator.thenComparing(userIdComparator); + } + + @NonNull + @Override + public List> apply( + @NonNull List> input) { + List> sorted = new ArrayList<>(input); + sorted.sort(mComparator); + return sorted; + } +} diff --git a/src/com/android/packageinstaller/role/ui/SpecialAppAccessListViewModel.java b/src/com/android/packageinstaller/role/ui/SpecialAppAccessListViewModel.java index dc7749b01..4933500ad 100644 --- a/src/com/android/packageinstaller/role/ui/SpecialAppAccessListViewModel.java +++ b/src/com/android/packageinstaller/role/ui/SpecialAppAccessListViewModel.java @@ -23,6 +23,7 @@ import android.os.UserHandle; import androidx.annotation.NonNull; import androidx.lifecycle.AndroidViewModel; import androidx.lifecycle.LiveData; +import androidx.lifecycle.Transformations; import androidx.lifecycle.ViewModel; import com.android.packageinstaller.role.utils.UserUtils; @@ -43,11 +44,13 @@ public class SpecialAppAccessListViewModel extends AndroidViewModel { UserHandle user = Process.myUserHandle(); RoleListLiveData liveData = new RoleListLiveData(false, user, application); UserHandle workProfile = UserUtils.getWorkProfile(application); + RoleListSortFunction sortFunction = new RoleListSortFunction(application); if (workProfile == null) { - mLiveData = liveData; + mLiveData = Transformations.map(liveData, sortFunction); } else { RoleListLiveData workLiveData = new RoleListLiveData(false, workProfile, application); - mLiveData = new MergeRoleListLiveData(liveData, workLiveData); + mLiveData = Transformations.map(new MergeRoleListLiveData(liveData, workLiveData), + sortFunction); } } diff --git a/src/com/android/packageinstaller/role/ui/SpecialAppAccessViewModel.java b/src/com/android/packageinstaller/role/ui/SpecialAppAccessViewModel.java index 417fee81a..64f0e72e8 100644 --- a/src/com/android/packageinstaller/role/ui/SpecialAppAccessViewModel.java +++ b/src/com/android/packageinstaller/role/ui/SpecialAppAccessViewModel.java @@ -27,6 +27,7 @@ import androidx.annotation.NonNull; import androidx.lifecycle.AndroidViewModel; import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.LiveData; +import androidx.lifecycle.Transformations; import androidx.lifecycle.ViewModel; import androidx.lifecycle.ViewModelProvider; @@ -55,11 +56,13 @@ public class SpecialAppAccessViewModel extends AndroidViewModel { UserHandle user = Process.myUserHandle(); RoleLiveData roleLiveData = new RoleLiveData(role, user, application); UserHandle workProfile = UserUtils.getWorkProfile(application); + RoleSortFunction sortFunction = new RoleSortFunction(application); if (workProfile == null) { - mRoleLiveData = roleLiveData; + mRoleLiveData = Transformations.map(roleLiveData, sortFunction); } else { RoleLiveData workRoleLiveData = new RoleLiveData(role, workProfile, application); - mRoleLiveData = new MergeRoleLiveData(roleLiveData, workRoleLiveData); + mRoleLiveData = Transformations.map(new MergeRoleLiveData(roleLiveData, + workRoleLiveData), sortFunction); } } -- GitLab From ff327d12fce43e3a345f7ad6791313b0971246cf Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Thu, 14 Feb 2019 11:41:41 -0800 Subject: [PATCH 363/701] Add confirmation message for assistant. This was inside DefaultAssistPicker in Settings. Also fixes isPackageQualified() for assistant. Bug: 124452117 Bug: 124395755 Test: manual Change-Id: Id8113f9dbcb936aa0425e34bc4d5d440f2d3f940 --- res/values/strings.xml | 5 ++++- .../role/model/AssistantRoleBehavior.java | 16 +++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index b3b348fc7..59de39fdc 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -536,9 +536,12 @@ Doesn\u2019t support work profile - + Note: If you restart your device and have a screen lock set, this app can\u2019t start until you unlock your device. + + The assistant will be able to read information about apps in use on your system, including information visible on your screen or accessible within the apps. + Share Debugging Data diff --git a/src/com/android/packageinstaller/role/model/AssistantRoleBehavior.java b/src/com/android/packageinstaller/role/model/AssistantRoleBehavior.java index 797fc6f5e..ec8db6391 100644 --- a/src/com/android/packageinstaller/role/model/AssistantRoleBehavior.java +++ b/src/com/android/packageinstaller/role/model/AssistantRoleBehavior.java @@ -16,9 +16,6 @@ package com.android.packageinstaller.role.model; -import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; -import static org.xmlpull.v1.XmlPullParser.START_TAG; - import android.app.ActivityManager; import android.content.Context; import android.content.Intent; @@ -38,6 +35,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.packageinstaller.role.utils.UserUtils; +import com.android.permissioncontroller.R; import org.xmlpull.v1.XmlPullParserException; @@ -50,6 +48,7 @@ import java.util.Set; * Class for behavior of the assistant role. */ public class AssistantRoleBehavior implements RoleBehavior { + private static final Intent ASSIST_SERVICE_PROBE = new Intent(VoiceInteractionService.SERVICE_INTERFACE); private static final Intent ASSIST_ACTIVITY_PROBE = new Intent(Intent.ACTION_ASSIST); @@ -75,6 +74,13 @@ public class AssistantRoleBehavior implements RoleBehavior { return new Intent(Settings.ACTION_VOICE_INPUT_SETTINGS); } + @Nullable + @Override + public CharSequence getConfirmationMessage(@NonNull Role role, @NonNull String packageName, + @NonNull Context context) { + return context.getString(R.string.assistant_confirmation_message); + } + @Nullable @Override public List getQualifyingPackagesAsUser(@NonNull Role role, @NonNull UserHandle user, @@ -113,7 +119,7 @@ public class AssistantRoleBehavior implements RoleBehavior { Intent pkgServiceProbe = new Intent(ASSIST_SERVICE_PROBE).setPackage(packageName); List services = pm.queryIntentServices(pkgServiceProbe, - PackageManager.MATCH_DEFAULT_ONLY); + PackageManager.GET_META_DATA); int numServices = services.size(); for (int i = 0; i < numServices; i++) { @@ -144,7 +150,7 @@ public class AssistantRoleBehavior implements RoleBehavior { int type; do { type = parser.next(); - } while (type != END_DOCUMENT && type != START_TAG); + } while (type != XmlResourceParser.END_DOCUMENT && type != XmlResourceParser.START_TAG); String sessionService = null; String recognitionService = null; -- GitLab From 1547185295f88a18b375f9b98a366d8cd765355b Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Thu, 14 Feb 2019 14:25:10 -0800 Subject: [PATCH 364/701] Check flag to see whether to show accessibility usage dialog. Test: Manually set/unset flag, see/don't see dialog. Change-Id: Iba5894b0796ff379e5dae2e8589c6a49867edd4e --- .../permission/ui/ReviewAccessibilityServicesActivity.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/com/android/packageinstaller/permission/ui/ReviewAccessibilityServicesActivity.java b/src/com/android/packageinstaller/permission/ui/ReviewAccessibilityServicesActivity.java index c920cf379..61df3f7f5 100644 --- a/src/com/android/packageinstaller/permission/ui/ReviewAccessibilityServicesActivity.java +++ b/src/com/android/packageinstaller/permission/ui/ReviewAccessibilityServicesActivity.java @@ -50,6 +50,10 @@ public final class ReviewAccessibilityServicesActivity extends FragmentActivity protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + if (!Utils.isPermissionsHubEnabled()) { + return; + } + new AlertDialog.Builder(this) .setView(createDialogView()) .setPositiveButton(R.string.ok, null) -- GitLab From 8b1b37d522b025ce58b75f1a7a8988c5656aa9b8 Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Wed, 13 Feb 2019 13:52:27 -0800 Subject: [PATCH 365/701] Add fallback holder for home role behavior. There is logic inside PackageManagerService and other parts of the system that allows using a home app without setting it as the default home (i.e. being configured as the preferred activity for home intent). This won't work in the new role mechanism because if it's used as the default home app, it should be set as the default home app, and setting an app as default home app means configuring it as the preferred activity. The only behavior change is that when a user installed another home app, and they were using the only home app and it wasn't manually selected so not configured as the preferred activity, they will not be presented with an intent disambiguation dialog when pressing home. But that's not a very big behavior change, because when they install a third home app, they will have to go to settings to change it anyway. Bug: 124260975 Test: manual Change-Id: Ide32c5fc218ba6e19dd45593d58a61c81fe03e9e --- res/xml/roles.xml | 1 + .../role/model/HomeRoleBehavior.java | 36 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/res/xml/roles.xml b/res/xml/roles.xml index eb685c3af..e1278d582 100644 --- a/res/xml/roles.xml +++ b/res/xml/roles.xml @@ -323,6 +323,7 @@ behavior="HomeRoleBehavior" exclusive="true" label="@string/role_label_home"> + diff --git a/src/com/android/packageinstaller/role/model/HomeRoleBehavior.java b/src/com/android/packageinstaller/role/model/HomeRoleBehavior.java index 627d5f2a6..87eb48e4f 100644 --- a/src/com/android/packageinstaller/role/model/HomeRoleBehavior.java +++ b/src/com/android/packageinstaller/role/model/HomeRoleBehavior.java @@ -26,11 +26,13 @@ import android.os.UserHandle; import android.provider.Settings; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.preference.Preference; import com.android.packageinstaller.role.utils.UserUtils; import com.android.permissioncontroller.R; +import java.util.List; import java.util.Objects; /** @@ -48,6 +50,40 @@ public class HomeRoleBehavior implements RoleBehavior { return !UserUtils.isWorkProfile(user, context); } + /** + * @see com.android.server.pm.PackageManagerService#getDefaultHomeActivity(int) + */ + @Nullable + @Override + public String getFallbackHolder(@NonNull Role role, @NonNull Context context) { + PackageManager packageManager = context.getPackageManager(); + Intent intent = role.getRequiredComponents().get(0).getIntentFilterData().createIntent(); + List resolveInfos = packageManager.queryIntentActivities(intent, + PackageManager.MATCH_DEFAULT_ONLY | PackageManager.MATCH_DIRECT_BOOT_AWARE + | PackageManager.MATCH_DIRECT_BOOT_UNAWARE); + + String packageName = null; + int priority = Integer.MIN_VALUE; + int resolveInfosSize = resolveInfos.size(); + for (int i = 0; i < resolveInfosSize; i++) { + ResolveInfo resolveInfo = resolveInfos.get(i); + + // Leave the fallback to PackageManagerService if there is only the fallback home in + // Settings, because if we fallback to it here, we cannot fallback to a normal home + // later, and user cannot see the fallback home in the UI anyway. + if (isSettingsApplication(resolveInfo.activityInfo.applicationInfo, context)) { + continue; + } + if (resolveInfo.priority > priority) { + packageName = resolveInfo.activityInfo.packageName; + priority = resolveInfo.priority; + } else if (resolveInfo.priority == priority) { + packageName = null; + } + } + return packageName; + } + @Override public void prepareApplicationPreferenceAsUser(@NonNull Role role, @NonNull Preference preference, @NonNull ApplicationInfo applicationInfo, -- GitLab From a492d2a0ca2b7d0c5b1e683ab926fbdf2c1a3ae2 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Thu, 14 Feb 2019 15:29:16 -0800 Subject: [PATCH 366/701] Temporarily hide the Permissions Hub spinners. Test: Open Permissions Hub. Change-Id: I8d5e6b83b0908795a033fd5335c77372f3a8b38d --- res/layout/permission_usage_filter_spinners.xml | 1 + .../permission/ui/handheld/PermissionUsageFragment.java | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/res/layout/permission_usage_filter_spinners.xml b/res/layout/permission_usage_filter_spinners.xml index 7e45ba8ee..201e163d6 100644 --- a/res/layout/permission_usage_filter_spinners.xml +++ b/res/layout/permission_usage_filter_spinners.xml @@ -17,6 +17,7 @@ Date: Sun, 20 Jan 2019 13:14:40 -0800 Subject: [PATCH 367/701] Move permission restore code into permission controller. This still follows the logic from the code that used to be in system server. Test: Built Change-Id: Ie1f4f7cd17ba59e18b15886d9c3ed038f14032a6 --- .../android/packageinstaller/Constants.java | 6 + .../permission/model/AppPermissionGroup.java | 47 +-- .../permission/service/BackupHelper.java | 333 +++++++++++++++++- .../PermissionControllerServiceImpl.java | 20 +- .../permission/service/TEST_MAPPING | 8 + 5 files changed, 389 insertions(+), 25 deletions(-) diff --git a/src/com/android/packageinstaller/Constants.java b/src/com/android/packageinstaller/Constants.java index f4de96e67..5083bfe84 100644 --- a/src/com/android/packageinstaller/Constants.java +++ b/src/com/android/packageinstaller/Constants.java @@ -84,4 +84,10 @@ public class Constants { * role holder for a role. */ public static final String IS_NONE_ROLE_HOLDER_SELECTED_KEY = "is_none_role_holder_selected:"; + + /** + * Name of file containing the permissions that should be restored, but have not been restored + * yet. + */ + public static final String DELAYED_RESTORE_PERMISSIONS_FILE = "delayed_restore_permissions.xml"; } diff --git a/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java b/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java index a5c3b88dd..9044c5ecf 100644 --- a/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java +++ b/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java @@ -26,6 +26,7 @@ import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE; import static android.app.AppOpsManager.MODE_ALLOWED; import static android.app.AppOpsManager.MODE_FOREGROUND; import static android.app.AppOpsManager.MODE_IGNORED; +import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import android.app.ActivityManager; @@ -889,13 +890,13 @@ public final class AppPermissionGroup implements Comparable continue; } - if (mAppSupportsRuntimePermissions) { - // Do not touch permissions fixed by the system. - if (permission.isSystemFixed()) { - wasAllRevoked = false; - break; - } + // Do not touch permissions fixed by the system. + if (permission.isSystemFixed()) { + wasAllRevoked = false; + break; + } + if (mAppSupportsRuntimePermissions) { // Revoke the permission if needed. if (permission.isGranted()) { permission.setGranted(false); @@ -1124,12 +1125,14 @@ public final class AppPermissionGroup implements Comparable for (int i = 0; i < numPermissions; i++) { Permission permission = mPermissions.valueAt(i); - if (permission.isGranted()) { - mPackageManager.grantRuntimePermission(mPackageInfo.packageName, - permission.getName(), mUserHandle); - } else { - mPackageManager.revokeRuntimePermission(mPackageInfo.packageName, - permission.getName(), mUserHandle); + if (!permission.isSystemFixed()) { + if (permission.isGranted()) { + mPackageManager.grantRuntimePermission(mPackageInfo.packageName, + permission.getName(), mUserHandle); + } else { + mPackageManager.revokeRuntimePermission(mPackageInfo.packageName, + permission.getName(), mUserHandle); + } } int flags = (permission.isUserSet() ? PackageManager.FLAG_PERMISSION_USER_SET : 0) @@ -1150,16 +1153,18 @@ public final class AppPermissionGroup implements Comparable flags, mUserHandle); if (permission.affectsAppOp()) { - if (permission.isAppOpAllowed()) { - allowAppOp(permission, mPackageInfo.applicationInfo.uid); - } else { - disallowAppOp(permission, mPackageInfo.applicationInfo.uid); - } + if (!permission.isSystemFixed()) { + if (permission.isAppOpAllowed()) { + allowAppOp(permission, mPackageInfo.applicationInfo.uid); + } else { + disallowAppOp(permission, mPackageInfo.applicationInfo.uid); + } - // Enabling/Disabling an app op may put the app in a situation in which it has a - // handle to state it shouldn't have, so we have to kill the app. This matches the - // revoke runtime permission behavior. - shouldKillApp = true; + // Enabling/Disabling an app op may put the app in a situation in which it has a + // handle to state it shouldn't have, so we have to kill the app. This matches + // the revoke runtime permission behavior. + shouldKillApp = true; + } } switch (permission.getName()) { diff --git a/src/com/android/packageinstaller/permission/service/BackupHelper.java b/src/com/android/packageinstaller/permission/service/BackupHelper.java index 39353bd70..245f23f3c 100644 --- a/src/com/android/packageinstaller/permission/service/BackupHelper.java +++ b/src/com/android/packageinstaller/permission/service/BackupHelper.java @@ -16,6 +16,7 @@ package com.android.packageinstaller.permission.service; +import static android.content.Context.MODE_PRIVATE; import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED; import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE; @@ -23,22 +24,39 @@ import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED; import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET; import static android.content.pm.PackageManager.GET_PERMISSIONS; +import static android.util.Xml.newSerializer; + +import static com.android.packageinstaller.Constants.DELAYED_RESTORE_PERMISSIONS_FILE; + +import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; +import static org.xmlpull.v1.XmlPullParser.END_TAG; +import static org.xmlpull.v1.XmlPullParser.START_TAG; + +import static java.nio.charset.StandardCharsets.UTF_8; import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.os.UserHandle; +import android.util.Log; +import android.util.Xml; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import com.android.packageinstaller.Constants; import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.model.AppPermissions; import com.android.packageinstaller.permission.model.Permission; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; +import java.io.File; +import java.io.FileInputStream; import java.io.IOException; +import java.io.OutputStream; import java.util.ArrayList; import java.util.List; @@ -46,6 +64,8 @@ import java.util.List; * Helper for creating and restoring permission backups. */ public class BackupHelper { + private static final String LOG_TAG = BackupHelper.class.getSimpleName(); + private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup"; private static final String TAG_ALL_GRANTS = "rt-grants"; @@ -69,6 +89,9 @@ public class BackupHelper { | FLAG_PERMISSION_USER_FIXED | FLAG_PERMISSION_REVOKE_ON_UPGRADE; + /** Make sure only one user can change the delayed permissions at a time */ + private static final Object sLock = new Object(); + private final Context mContext; /** @@ -85,6 +108,134 @@ public class BackupHelper { } } + /** + * Forward parser and skip everything up to the end of the current tag. + * + * @param parser The parser to forward + */ + private static void skipToEndOfTag(@NonNull XmlPullParser parser) + throws IOException, XmlPullParserException { + int numOpenTags = 1; + while (numOpenTags > 0) { + switch (parser.next()) { + case START_TAG: + numOpenTags++; + break; + case END_TAG: + numOpenTags--; + break; + default: + // ignore + } + } + } + + /** + * Forward parser to a given direct sub-tag. + * + * @param parser The parser to forward + * @param tag The tag to search for + */ + private void skipToTag(@NonNull XmlPullParser parser, @NonNull String tag) + throws IOException, XmlPullParserException { + int type; + do { + type = parser.next(); + + switch (type) { + case START_TAG: + if (!parser.getName().equals(tag)) { + skipToEndOfTag(parser); + } + + return; + } + } while (type != END_DOCUMENT); + } + + /** + * Read a XML file and return the packages stored in it. + * + * @param parser The file to read + * + * @return The packages in this file + */ + private @NonNull ArrayList parseFromXml(@NonNull XmlPullParser parser) + throws IOException, XmlPullParserException { + ArrayList pkgStates = new ArrayList<>(); + + skipToTag(parser, TAG_PERMISSION_BACKUP); + skipToTag(parser, TAG_ALL_GRANTS); + + if (parser.getEventType() != START_TAG && !parser.getName().equals(TAG_ALL_GRANTS)) { + throw new XmlPullParserException("Could not find " + TAG_PERMISSION_BACKUP + " > " + + TAG_ALL_GRANTS); + } + + // Read packages to restore from xml + int type; + do { + type = parser.next(); + + switch (type) { + case START_TAG: + switch (parser.getName()) { + case TAG_GRANT: + try { + pkgStates.add(BackupPackageState.parseFromXml(parser)); + } catch (XmlPullParserException e) { + Log.e(LOG_TAG, "Could not parse permissions ", e); + skipToEndOfTag(parser); + } + break; + default: + // ignore tag + Log.w(LOG_TAG, "Found unexpected tag " + parser.getName() + + " during restore"); + skipToEndOfTag(parser); + } + } + } while (type != END_TAG); + + return pkgStates; + } + + /** + * Try to restore the permission state from XML. + * + *

If some apps could not be restored, the leftover apps are written to + * {@link Constants#DELAYED_RESTORE_PERMISSIONS_FILE}. + * + * @param parser The xml to read + */ + void restoreState(@NonNull XmlPullParser parser) throws IOException, XmlPullParserException { + ArrayList pkgStates = parseFromXml(parser); + + ArrayList packagesToRestoreLater = new ArrayList<>(); + int numPkgStates = pkgStates.size(); + if (numPkgStates > 0) { + // Try to restore packages + for (int i = 0; i < numPkgStates; i++) { + BackupPackageState pkgState = pkgStates.get(i); + + PackageInfo pkgInfo; + try { + pkgInfo = mContext.getPackageManager().getPackageInfo(pkgState.mPackageName, + GET_PERMISSIONS); + } catch (PackageManager.NameNotFoundException ignored) { + packagesToRestoreLater.add(pkgState); + continue; + } + + pkgState.restore(mContext, pkgInfo); + } + } + + synchronized (sLock) { + writeDelayedStorePkgsLocked(packagesToRestoreLater); + } + } + /** * Write a xml file for the given packages. * @@ -113,6 +264,26 @@ public class BackupHelper { serializer.endDocument(); } + /** + * Update the {@link Constants#DELAYED_RESTORE_PERMISSIONS_FILE} to contain the + * {@code packagesToRestoreLater}. + * + * @param packagesToRestoreLater The new pkgs in the delayed restore file + */ + private void writeDelayedStorePkgsLocked( + @NonNull ArrayList packagesToRestoreLater) { + try (OutputStream delayedRestoreData = mContext.openFileOutput( + DELAYED_RESTORE_PERMISSIONS_FILE, MODE_PRIVATE)) { + XmlSerializer serializer = newSerializer(); + serializer.setOutput(delayedRestoreData, UTF_8.name()); + + writePkgsAsXml(serializer, packagesToRestoreLater); + serializer.flush(); + } catch (IOException e) { + Log.e(LOG_TAG, "Could not remember which packages still need to be restored", e); + } + } + /** * Write the state of all packages as XML. * @@ -136,6 +307,55 @@ public class BackupHelper { writePkgsAsXml(serializer, backupPkgs); } + /** + * Restore delayed permission state for a package (if delayed during {@link #restoreState}). + * + * @param packageName The package to be restored + * + * @return {@code true} if there is still delayed backup left + */ + boolean restoreDelayedState(@NonNull String packageName) { + synchronized (sLock) { + ArrayList packagesToRestoreLater; + + try (FileInputStream delayedRestoreData = + mContext.openFileInput(DELAYED_RESTORE_PERMISSIONS_FILE)) { + XmlPullParser parser = Xml.newPullParser(); + parser.setInput(delayedRestoreData, UTF_8.name()); + + packagesToRestoreLater = parseFromXml(parser); + } catch (IOException | XmlPullParserException e) { + Log.e(LOG_TAG, "Could not parse delayed permissions", e); + return false; + } + + PackageInfo pkgInfo = null; + try { + pkgInfo = mContext.getPackageManager().getPackageInfo(packageName, GET_PERMISSIONS); + } catch (PackageManager.NameNotFoundException e) { + Log.e(LOG_TAG, "Could not restore delayed permissions for " + packageName, e); + } + + if (pkgInfo != null) { + int numPkgs = packagesToRestoreLater.size(); + for (int i = 0; i < numPkgs; i++) { + BackupPackageState pkgState = packagesToRestoreLater.get(i); + + if (pkgState.mPackageName.equals(packageName)) { + pkgState.restore(mContext, pkgInfo); + packagesToRestoreLater.remove(i); + + writeDelayedStorePkgsLocked(packagesToRestoreLater); + + break; + } + } + } + + return packagesToRestoreLater.size() > 0; + } + } + /** * State that needs to be backed up for a permission. */ @@ -155,6 +375,28 @@ public class BackupHelper { mShouldRevokeOnUpgrade = isRevokeOnUpgrade; } + /** + * Parse a package state from XML. + * + * @param parser The data to read + * + * @return The state + */ + static @NonNull BackupPermissionState parseFromXml(@NonNull XmlPullParser parser) + throws XmlPullParserException { + String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME); + if (permName == null) { + throw new XmlPullParserException("Found " + TAG_PERMISSION + " without " + + ATTR_PERMISSION_NAME); + } + + return new BackupPermissionState(permName, + "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED)), + "true".equals(parser.getAttributeValue(null, ATTR_USER_SET)), + "true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED)), + "true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))); + } + /** * Get the state of a permission to back up. * @@ -227,13 +469,37 @@ public class BackupHelper { serializer.endTag(null, TAG_PERMISSION); } + + /** + * Restore this permission state. + * + * @param appPerms The {@link AppPermissions} to restore the state to + */ + void restore(@NonNull AppPermissions appPerms) { + AppPermissionGroup group = appPerms.getGroupForPermission(mPermissionName); + if (group == null) { + Log.w(LOG_TAG, "Could not find group for " + mPermissionName + " in " + + appPerms.getPackageInfo().packageName); + return; + } + + if (mIsGranted) { + group.grantRuntimePermissions(/* is overridden below */false, + new String[]{mPermissionName}); + } + + Permission perm = group.getPermission(mPermissionName); + perm.setUserSet(mIsUserSet); + perm.setUserFixed(mIsUserFixed); + perm.setRevokeOnUpgrade(mShouldRevokeOnUpgrade); + } } /** * State that needs to be backed up for a package. */ private static class BackupPackageState { - private final @NonNull String mPackageName; + final @NonNull String mPackageName; private final @NonNull ArrayList mPermissionsToRestore; private BackupPackageState(@NonNull String packageName, @@ -242,6 +508,54 @@ public class BackupHelper { mPermissionsToRestore = permissionsToRestore; } + /** + * Parse a package state from XML. + * + * @param parser The data to read + * + * @return The state + */ + static @NonNull BackupPackageState parseFromXml(@NonNull XmlPullParser parser) + throws IOException, XmlPullParserException { + String packageName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME); + if (packageName == null) { + throw new XmlPullParserException("Found " + TAG_GRANT + " without " + + ATTR_PACKAGE_NAME); + } + + ArrayList permissionsToRestore = new ArrayList<>(); + + while (true) { + switch (parser.next()) { + case START_TAG: + switch (parser.getName()) { + case TAG_PERMISSION: + try { + permissionsToRestore.add( + BackupPermissionState.parseFromXml(parser)); + } catch (XmlPullParserException e) { + Log.e(LOG_TAG, "Could not parse permission for " + + packageName, e); + skipToEndOfTag(parser); + } + break; + default: + // ignore tag + Log.w(LOG_TAG, "Found unexpected tag " + parser.getName() + + " while restoring " + packageName); + skipToEndOfTag(parser); + } + + break; + case END_TAG: + return new BackupPackageState(packageName, permissionsToRestore); + case END_DOCUMENT: + throw new XmlPullParserException("Could not parse state for " + + packageName); + } + } + } + /** * Get the state of a package to back up. * @@ -299,5 +613,22 @@ public class BackupHelper { serializer.endTag(null, TAG_GRANT); } + + /** + * Restore this package state. + * + * @param context A context to use + * @param pkgInfo The package to restore. + */ + void restore(@NonNull Context context, @NonNull PackageInfo pkgInfo) { + AppPermissions appPerms = new AppPermissions(context, pkgInfo, false, true, null); + + int numPerms = mPermissionsToRestore.size(); + for (int i = 0; i < numPerms; i++) { + mPermissionsToRestore.get(i).restore(appPerms); + } + + appPerms.persistChanges(); + } } } diff --git a/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java b/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java index f24049bd1..5f3d24db4 100644 --- a/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java +++ b/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java @@ -40,6 +40,7 @@ import android.permission.RuntimePermissionUsageInfo; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Log; +import android.util.Xml; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -53,10 +54,12 @@ import com.android.packageinstaller.permission.model.PermissionUsages; import com.android.packageinstaller.permission.utils.Utils; import com.android.packageinstaller.role.service.PermissionControllerServiceImplRoleMixin; +import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlSerializer; import java.io.InputStream; import java.io.OutputStream; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -306,14 +309,25 @@ public final class PermissionControllerServiceImpl extends PermissionControllerS @Override public void onRestoreRuntimePermissionsBackup(@NonNull UserHandle user, @NonNull InputStream backup) { - // TODO: Implement + try { + XmlPullParser parser = Xml.newPullParser(); + parser.setInput(backup, StandardCharsets.UTF_8.name()); + + new BackupHelper(this, user).restoreState(parser); + } catch (Exception e) { + Log.e(LOG_TAG, "Exception restoring permissions: " + e.getMessage()); + } } @Override public boolean onRestoreDelayedRuntimePermissionsBackup(@NonNull String packageName, @NonNull UserHandle user) { - // TODO: Implement - return true; + try { + return new BackupHelper(this, user).restoreDelayedState(packageName); + } catch (Exception e) { + Log.e(LOG_TAG, "Exception restoring delayed permissions: " + e.getMessage()); + return false; + } } @Override diff --git a/src/com/android/packageinstaller/permission/service/TEST_MAPPING b/src/com/android/packageinstaller/permission/service/TEST_MAPPING index 64c032ce9..c11483969 100644 --- a/src/com/android/packageinstaller/permission/service/TEST_MAPPING +++ b/src/com/android/packageinstaller/permission/service/TEST_MAPPING @@ -10,6 +10,14 @@ "include-filter": "android.permission.cts.PermissionControllerTest" } ] + }, + { + "name": "CtsBackupTestCases", + "options": [ + { + "include-filter": "android.backup.cts.PermissionTest" + } + ] } ] } -- GitLab From 462989ee09fa2ae0d74244ab984783d57fee6147 Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Wed, 6 Feb 2019 09:31:21 -0800 Subject: [PATCH 368/701] Do not backup and restore revoke-on-upgrade The flag is set and reset by the system at the appropriate time. The user cannot control it. We only need up backup flags that might have been changed by the user. Test: Built Change-Id: I22d8f74db970ed6cf84f1b0054a6b38e9fc6a482 --- .../permission/service/BackupHelper.java | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/com/android/packageinstaller/permission/service/BackupHelper.java b/src/com/android/packageinstaller/permission/service/BackupHelper.java index 245f23f3c..2f0e96cd0 100644 --- a/src/com/android/packageinstaller/permission/service/BackupHelper.java +++ b/src/com/android/packageinstaller/permission/service/BackupHelper.java @@ -364,15 +364,13 @@ public class BackupHelper { private final boolean mIsGranted; private final boolean mIsUserSet; private final boolean mIsUserFixed; - private final boolean mShouldRevokeOnUpgrade; private BackupPermissionState(@NonNull String permissionName, boolean isGranted, - boolean isUserSet, boolean isUserFixed, boolean isRevokeOnUpgrade) { + boolean isUserSet, boolean isUserFixed) { mPermissionName = permissionName; mIsGranted = isGranted; mIsUserSet = isUserSet; mIsUserFixed = isUserFixed; - mShouldRevokeOnUpgrade = isRevokeOnUpgrade; } /** @@ -393,8 +391,7 @@ public class BackupHelper { return new BackupPermissionState(permName, "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED)), "true".equals(parser.getAttributeValue(null, ATTR_USER_SET)), - "true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED)), - "true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))); + "true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))); } /** @@ -411,7 +408,7 @@ public class BackupHelper { if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0 && (perm.isGranted() || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0)) { return new BackupPermissionState(perm.getName(), perm.isGranted(), - perm.isUserSet(), perm.isUserFixed(), perm.shouldRevokeOnUpgrade()); + perm.isUserSet(), perm.isUserFixed()); } else { return null; } @@ -463,10 +460,6 @@ public class BackupHelper { serializer.attribute(null, ATTR_USER_FIXED, "true"); } - if (mShouldRevokeOnUpgrade) { - serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true"); - } - serializer.endTag(null, TAG_PERMISSION); } @@ -491,7 +484,6 @@ public class BackupHelper { Permission perm = group.getPermission(mPermissionName); perm.setUserSet(mIsUserSet); perm.setUserFixed(mIsUserFixed); - perm.setRevokeOnUpgrade(mShouldRevokeOnUpgrade); } } -- GitLab From 6f08e5d54a5c525888a09f66990ace0d652e4bbf Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Wed, 6 Feb 2019 09:55:00 -0800 Subject: [PATCH 369/701] Backup if a permission of a pre-M app was reviewed - The default state for a pre-M add is that the permission needs to be reviewed - Post-M apps never use the flag Test: Built Change-Id: Ic21018480030245c179baa13b2e3f0c3ad409377 --- .../permission/model/AppPermissionGroup.java | 6 +- .../permission/model/Permission.java | 2 +- .../permission/service/BackupHelper.java | 55 +++++++++++++------ .../PermissionControllerServiceImpl.java | 2 +- .../handheld/ReviewPermissionsFragment.java | 4 +- .../wear/ReviewPermissionsWearFragment.java | 2 +- 6 files changed, 45 insertions(+), 26 deletions(-) diff --git a/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java b/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java index 9044c5ecf..7aa59648a 100644 --- a/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java +++ b/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java @@ -429,12 +429,12 @@ public final class AppPermissionGroup implements Comparable return false; } - public void resetReviewRequired() { + public void unsetReviewRequired() { final int permissionCount = mPermissions.size(); for (int i = 0; i < permissionCount; i++) { Permission permission = mPermissions.valueAt(i); if (permission.isReviewRequired()) { - permission.resetReviewRequired(); + permission.unsetReviewRequired(); } } @@ -781,7 +781,7 @@ public final class AppPermissionGroup implements Comparable // Granting a permission explicitly means the user already // reviewed it so clear the review flag on every grant. if (permission.isReviewRequired()) { - permission.resetReviewRequired(); + permission.unsetReviewRequired(); } } diff --git a/src/com/android/packageinstaller/permission/model/Permission.java b/src/com/android/packageinstaller/permission/model/Permission.java index 5d12d4465..617a00833 100644 --- a/src/com/android/packageinstaller/permission/model/Permission.java +++ b/src/com/android/packageinstaller/permission/model/Permission.java @@ -134,7 +134,7 @@ public final class Permission { return (mFlags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0; } - public void resetReviewRequired() { + public void unsetReviewRequired() { mFlags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED; } diff --git a/src/com/android/packageinstaller/permission/service/BackupHelper.java b/src/com/android/packageinstaller/permission/service/BackupHelper.java index 2f0e96cd0..6e3f5948c 100644 --- a/src/com/android/packageinstaller/permission/service/BackupHelper.java +++ b/src/com/android/packageinstaller/permission/service/BackupHelper.java @@ -19,10 +19,7 @@ package com.android.packageinstaller.permission.service; import static android.content.Context.MODE_PRIVATE; import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED; -import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE; import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; -import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED; -import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET; import static android.content.pm.PackageManager.GET_PERMISSIONS; import static android.util.Xml.newSerializer; @@ -37,6 +34,7 @@ import static java.nio.charset.StandardCharsets.UTF_8; import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; +import android.os.Build; import android.os.UserHandle; import android.util.Log; import android.util.Xml; @@ -77,17 +75,11 @@ public class BackupHelper { private static final String ATTR_IS_GRANTED = "g"; private static final String ATTR_USER_SET = "set"; private static final String ATTR_USER_FIXED = "fixed"; - private static final String ATTR_REVOKE_ON_UPGRADE = "rou"; + private static final String ATTR_WAS_REVIEWED = "was-reviewed"; /** Flags of permissions to not back up */ private static final int SYSTEM_RUNTIME_GRANT_MASK = FLAG_PERMISSION_POLICY_FIXED - | FLAG_PERMISSION_SYSTEM_FIXED - | FLAG_PERMISSION_GRANTED_BY_DEFAULT; - - /** Flags that need to be backed up even if permission is revoked */ - private static final int USER_RUNTIME_GRANT_MASK = FLAG_PERMISSION_USER_SET - | FLAG_PERMISSION_USER_FIXED - | FLAG_PERMISSION_REVOKE_ON_UPGRADE; + | FLAG_PERMISSION_SYSTEM_FIXED; /** Make sure only one user can change the delayed permissions at a time */ private static final Object sLock = new Object(); @@ -364,13 +356,15 @@ public class BackupHelper { private final boolean mIsGranted; private final boolean mIsUserSet; private final boolean mIsUserFixed; + private final boolean mWasReviewed; private BackupPermissionState(@NonNull String permissionName, boolean isGranted, - boolean isUserSet, boolean isUserFixed) { + boolean isUserSet, boolean isUserFixed, boolean wasReviewed) { mPermissionName = permissionName; mIsGranted = isGranted; mIsUserSet = isUserSet; mIsUserFixed = isUserFixed; + mWasReviewed = wasReviewed; } /** @@ -391,24 +385,37 @@ public class BackupHelper { return new BackupPermissionState(permName, "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED)), "true".equals(parser.getAttributeValue(null, ATTR_USER_SET)), - "true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))); + "true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED)), + "true".equals(parser.getAttributeValue(null, ATTR_WAS_REVIEWED))); } /** * Get the state of a permission to back up. * * @param perm The permission to back up + * @param appSupportsRuntimePermissions If the app supports runtimePermissions * * @return The state to back up or {@code null} if the permission does not need to be * backed up. */ - private static @Nullable BackupPermissionState fromPermission(@NonNull Permission perm) { + private static @Nullable BackupPermissionState fromPermission(@NonNull Permission perm, + boolean appSupportsRuntimePermissions) { int grantFlags = perm.getFlags(); - if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0 - && (perm.isGranted() || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0)) { + if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) != 0) { + return null; + } + + if (!perm.isUserSet() && perm.isGrantedByDefault()) { + return null; + } + + boolean permissionWasReviewed = + !appSupportsRuntimePermissions && !perm.isReviewRequired(); + + if (perm.isGranted() || perm.isUserSet() || perm.isUserFixed() || permissionWasReviewed) { return new BackupPermissionState(perm.getName(), perm.isGranted(), - perm.isUserSet(), perm.isUserFixed()); + perm.isUserSet(), perm.isUserFixed(), permissionWasReviewed); } else { return null; } @@ -427,9 +434,13 @@ public class BackupHelper { ArrayList permissionsToRestore = new ArrayList<>(); List perms = group.getPermissions(); + boolean appSupportsRuntimePermissions = + group.getApp().applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M; + int numPerms = perms.size(); for (int i = 0; i < numPerms; i++) { - BackupPermissionState permState = fromPermission(perms.get(i)); + BackupPermissionState permState = fromPermission(perms.get(i), + appSupportsRuntimePermissions); if (permState != null) { permissionsToRestore.add(permState); } @@ -460,6 +471,10 @@ public class BackupHelper { serializer.attribute(null, ATTR_USER_FIXED, "true"); } + if (mWasReviewed) { + serializer.attribute(null, ATTR_WAS_REVIEWED, "true"); + } + serializer.endTag(null, TAG_PERMISSION); } @@ -484,6 +499,10 @@ public class BackupHelper { Permission perm = group.getPermission(mPermissionName); perm.setUserSet(mIsUserSet); perm.setUserFixed(mIsUserFixed); + + if (mWasReviewed) { + perm.unsetReviewRequired(); + } } } diff --git a/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java b/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java index 5f3d24db4..39caf0e72 100644 --- a/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java +++ b/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java @@ -185,7 +185,7 @@ public final class PermissionControllerServiceImpl extends PermissionControllerS // Mark the permissions as reviewed as we don't want to use to accidentally grant // the permission during review - group.resetReviewRequired(); + group.unsetReviewRequired(); int numPerms = perms.size(); for (int permNum = 0; permNum < numPerms; permNum++) { diff --git a/src/com/android/packageinstaller/permission/ui/handheld/ReviewPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/ReviewPermissionsFragment.java index 4a39838e9..dd854b746 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/ReviewPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/ReviewPermissionsFragment.java @@ -197,7 +197,7 @@ public final class ReviewPermissionsFragment extends PreferenceFragmentCompat if (group.isReviewRequired() && !permPreference.wasChanged()) { grantReviewedPermission(group); } - group.resetReviewRequired(); + group.unsetReviewRequired(); AppPermissionGroup backgroundGroup = group.getBackgroundPermissions(); if (backgroundGroup != null) { @@ -205,7 +205,7 @@ public final class ReviewPermissionsFragment extends PreferenceFragmentCompat if (backgroundGroup.isReviewRequired() && !permPreference.wasChanged()) { grantReviewedPermission(backgroundGroup); } - backgroundGroup.resetReviewRequired(); + backgroundGroup.unsetReviewRequired(); } } } diff --git a/src/com/android/packageinstaller/permission/ui/wear/ReviewPermissionsWearFragment.java b/src/com/android/packageinstaller/permission/ui/wear/ReviewPermissionsWearFragment.java index 6397cd7c0..4840fb3c6 100644 --- a/src/com/android/packageinstaller/permission/ui/wear/ReviewPermissionsWearFragment.java +++ b/src/com/android/packageinstaller/permission/ui/wear/ReviewPermissionsWearFragment.java @@ -253,7 +253,7 @@ public class ReviewPermissionsWearFragment extends PreferenceFragmentCompat } else { group.revokeRuntimePermissions(false); } - group.resetReviewRequired(); + group.unsetReviewRequired(); } } } -- GitLab From 21c8dc257b11f73024324554100a71a0298bc7ab Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Wed, 6 Feb 2019 09:59:23 -0800 Subject: [PATCH 370/701] Correctly backup granted state for pre-M apps Pre-M apps always have the permission granted. The revocation state is stored inside of the app-op matching the permission. Hence we have to take the app-op into account when backing up the permission. Please note that if the permission still requires review, the permission state is irrelevant as it will always be overridden during review. The restore path already calls group.grantRuntimePermissions which handles the app-ops correctly. Test: Built Change-Id: Ic151c61839292ca88f71bf54b23ccd6ff20f3c69 --- .../packageinstaller/permission/service/BackupHelper.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/com/android/packageinstaller/permission/service/BackupHelper.java b/src/com/android/packageinstaller/permission/service/BackupHelper.java index 6e3f5948c..3db9efc01 100644 --- a/src/com/android/packageinstaller/permission/service/BackupHelper.java +++ b/src/com/android/packageinstaller/permission/service/BackupHelper.java @@ -413,8 +413,9 @@ public class BackupHelper { boolean permissionWasReviewed = !appSupportsRuntimePermissions && !perm.isReviewRequired(); - if (perm.isGranted() || perm.isUserSet() || perm.isUserFixed() || permissionWasReviewed) { - return new BackupPermissionState(perm.getName(), perm.isGranted(), + if (perm.isGrantedIncludingAppOp() || perm.isUserSet() || perm.isUserFixed() + || permissionWasReviewed) { + return new BackupPermissionState(perm.getName(), perm.isGrantedIncludingAppOp(), perm.isUserSet(), perm.isUserFixed(), permissionWasReviewed); } else { return null; -- GitLab From e04504217a9a62aa6aabaa9091097144bd404aaf Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Wed, 6 Feb 2019 14:26:57 -0800 Subject: [PATCH 371/701] Be careful what state to restore ... don't override policy, system or user Test: Built Change-Id: Iecb4d0bd5f93f78777f25a58a75334327b63ad91 --- .../permission/model/AppPermissionGroup.java | 17 ++++ .../permission/service/BackupHelper.java | 87 ++++++++++++++++--- 2 files changed, 90 insertions(+), 14 deletions(-) diff --git a/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java b/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java index 7aa59648a..df077f793 100644 --- a/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java +++ b/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java @@ -969,6 +969,23 @@ public final class AppPermissionGroup implements Comparable } } + /** + * Set the user-fixed flag for all permissions in this group. + * + * @param isUsedFixed if the flag should be set or not + */ + public void setUserFixed(boolean isUsedFixed) { + final int permissionCount = mPermissions.size(); + for (int i = 0; i < permissionCount; i++) { + Permission permission = mPermissions.valueAt(i); + permission.setUserFixed(isUsedFixed); + } + + if (!mDelayChanges) { + persistChanges(false); + } + } + public ArrayList getPermissions() { return new ArrayList<>(mPermissions.values()); } diff --git a/src/com/android/packageinstaller/permission/service/BackupHelper.java b/src/com/android/packageinstaller/permission/service/BackupHelper.java index 3db9efc01..a3982c76d 100644 --- a/src/com/android/packageinstaller/permission/service/BackupHelper.java +++ b/src/com/android/packageinstaller/permission/service/BackupHelper.java @@ -187,7 +187,7 @@ public class BackupHelper { skipToEndOfTag(parser); } } - } while (type != END_TAG); + } while (type != END_DOCUMENT); return pkgStates; } @@ -389,6 +389,19 @@ public class BackupHelper { "true".equals(parser.getAttributeValue(null, ATTR_WAS_REVIEWED))); } + /** + * Is the permission granted, also considering the app-op. + * + *

This does not consider the review-required state of the permission. + * + * @param perm The permission that might be granted + * + * @return {@code true} iff the permission and app-op is granted + */ + private static boolean isPermGrantedIncludingAppOp(@NonNull Permission perm) { + return perm.isGranted() && (!perm.affectsAppOp() || perm.isAppOpAllowed()); + } + /** * Get the state of a permission to back up. * @@ -410,12 +423,19 @@ public class BackupHelper { return null; } - boolean permissionWasReviewed = - !appSupportsRuntimePermissions && !perm.isReviewRequired(); + boolean permissionWasReviewed; + boolean isNotInDefaultGrantState; + if (appSupportsRuntimePermissions) { + isNotInDefaultGrantState = isPermGrantedIncludingAppOp(perm); + permissionWasReviewed = false; + } else { + isNotInDefaultGrantState = !isPermGrantedIncludingAppOp(perm); + permissionWasReviewed = !perm.isReviewRequired(); + } - if (perm.isGrantedIncludingAppOp() || perm.isUserSet() || perm.isUserFixed() + if (isNotInDefaultGrantState || perm.isUserSet() || perm.isUserFixed() || permissionWasReviewed) { - return new BackupPermissionState(perm.getName(), perm.isGrantedIncludingAppOp(), + return new BackupPermissionState(perm.getName(), isPermGrantedIncludingAppOp(perm), perm.isUserSet(), perm.isUserFixed(), permissionWasReviewed); } else { return null; @@ -483,8 +503,10 @@ public class BackupHelper { * Restore this permission state. * * @param appPerms The {@link AppPermissions} to restore the state to + * @param restoreBackgroundPerms if {@code true} only restore background permissions, + * if {@code false} do not restore background permissions */ - void restore(@NonNull AppPermissions appPerms) { + void restore(@NonNull AppPermissions appPerms, boolean restoreBackgroundPerms) { AppPermissionGroup group = appPerms.getGroupForPermission(mPermissionName); if (group == null) { Log.w(LOG_TAG, "Could not find group for " + mPermissionName + " in " @@ -492,18 +514,31 @@ public class BackupHelper { return; } - if (mIsGranted) { - group.grantRuntimePermissions(/* is overridden below */false, - new String[]{mPermissionName}); + if (restoreBackgroundPerms != group.isBackgroundGroup()) { + return; } Permission perm = group.getPermission(mPermissionName); - perm.setUserSet(mIsUserSet); - perm.setUserFixed(mIsUserFixed); - if (mWasReviewed) { perm.unsetReviewRequired(); } + + // Don't grant or revoke fixed permission groups + if (group.isSystemFixed() || group.isPolicyFixed()) { + return; + } + + if (!perm.isUserSet()) { + if (mIsGranted) { + group.grantRuntimePermissions(mIsUserFixed, + new String[]{mPermissionName}); + } else { + group.revokeRuntimePermissions(mIsUserFixed, + new String[]{mPermissionName}); + } + + perm.setUserSet(mIsUserSet); + } } } @@ -548,8 +583,9 @@ public class BackupHelper { } catch (XmlPullParserException e) { Log.e(LOG_TAG, "Could not parse permission for " + packageName, e); - skipToEndOfTag(parser); } + + skipToEndOfTag(parser); break; default: // ignore tag @@ -635,9 +671,32 @@ public class BackupHelper { void restore(@NonNull Context context, @NonNull PackageInfo pkgInfo) { AppPermissions appPerms = new AppPermissions(context, pkgInfo, false, true, null); + // Restore background permissions after foreground permissions as for pre-M apps bg + // granted and fg revoked cannot be expressed. int numPerms = mPermissionsToRestore.size(); for (int i = 0; i < numPerms; i++) { - mPermissionsToRestore.get(i).restore(appPerms); + mPermissionsToRestore.get(i).restore(appPerms, false); + } + for (int i = 0; i < numPerms; i++) { + mPermissionsToRestore.get(i).restore(appPerms, true); + } + + int numGroups = appPerms.getPermissionGroups().size(); + for (int i = 0; i < numGroups; i++) { + AppPermissionGroup group = appPerms.getPermissionGroups().get(i); + + // Only denied groups can be user fixed + if (group.areRuntimePermissionsGranted()) { + group.setUserFixed(false); + } + + AppPermissionGroup bgGroup = group.getBackgroundPermissions(); + if (bgGroup != null) { + // Only denied groups can be user fixed + if (bgGroup.areRuntimePermissionsGranted()) { + bgGroup.setUserFixed(false); + } + } } appPerms.persistChanges(); -- GitLab From 0d54491c2031f1901ed0028a790f483c98258e8c Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Wed, 6 Feb 2019 13:38:31 -0800 Subject: [PATCH 372/701] Inherit state into split permissions by just inheriting the state Test: Built Change-Id: I62a234f243f79d7d85ec5c58e964f2e7729a6768 --- .../permission/service/BackupHelper.java | 71 ++++++++++++++++--- 1 file changed, 61 insertions(+), 10 deletions(-) diff --git a/src/com/android/packageinstaller/permission/service/BackupHelper.java b/src/com/android/packageinstaller/permission/service/BackupHelper.java index a3982c76d..ab0471624 100644 --- a/src/com/android/packageinstaller/permission/service/BackupHelper.java +++ b/src/com/android/packageinstaller/permission/service/BackupHelper.java @@ -36,6 +36,8 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.os.Build; import android.os.UserHandle; +import android.permission.PermissionManager; +import android.permission.PermissionManager.SplitPermissionInfo; import android.util.Log; import android.util.Xml; @@ -65,6 +67,8 @@ public class BackupHelper { private static final String LOG_TAG = BackupHelper.class.getSimpleName(); private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup"; + private static final String ATTR_PLATFORM_VERSION = "version"; + private static final String TAG_ALL_GRANTS = "rt-grants"; private static final String TAG_GRANT = "grant"; @@ -157,6 +161,16 @@ public class BackupHelper { ArrayList pkgStates = new ArrayList<>(); skipToTag(parser, TAG_PERMISSION_BACKUP); + + int backupPlatformVersion; + try { + backupPlatformVersion = Integer.parseInt( + parser.getAttributeValue(null, ATTR_PLATFORM_VERSION)); + } catch (NumberFormatException ignored) { + // Platforms P and before did not store the platform version + backupPlatformVersion = Build.VERSION_CODES.P; + } + skipToTag(parser, TAG_ALL_GRANTS); if (parser.getEventType() != START_TAG && !parser.getName().equals(TAG_ALL_GRANTS)) { @@ -174,7 +188,8 @@ public class BackupHelper { switch (parser.getName()) { case TAG_GRANT: try { - pkgStates.add(BackupPackageState.parseFromXml(parser)); + pkgStates.add(BackupPackageState.parseFromXml(parser, mContext, + backupPlatformVersion)); } catch (XmlPullParserException e) { Log.e(LOG_TAG, "Could not parse permissions ", e); skipToEndOfTag(parser); @@ -239,6 +254,9 @@ public class BackupHelper { serializer.startDocument(null, true); serializer.startTag(null, TAG_PERMISSION_BACKUP); + serializer.attribute(null, ATTR_PLATFORM_VERSION, + Integer.valueOf(Build.VERSION.SDK_INT).toString()); + serializer.startTag(null, TAG_ALL_GRANTS); int numPkgs = pkgs.size(); @@ -371,10 +389,13 @@ public class BackupHelper { * Parse a package state from XML. * * @param parser The data to read + * @param context a context to use + * @param backupPlatformVersion The platform version the backup was created on * * @return The state */ - static @NonNull BackupPermissionState parseFromXml(@NonNull XmlPullParser parser) + static @NonNull ArrayList parseFromXml(@NonNull XmlPullParser parser, + @NonNull Context context, int backupPlatformVersion) throws XmlPullParserException { String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME); if (permName == null) { @@ -382,11 +403,37 @@ public class BackupHelper { + ATTR_PERMISSION_NAME); } - return new BackupPermissionState(permName, - "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED)), - "true".equals(parser.getAttributeValue(null, ATTR_USER_SET)), - "true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED)), - "true".equals(parser.getAttributeValue(null, ATTR_WAS_REVIEWED))); + ArrayList expandedPermissions = new ArrayList<>(); + expandedPermissions.add(permName); + + List splitPerms = context.getSystemService( + PermissionManager.class).getSplitPermissions(); + + // Expand the properties to permissions that were split between the platform version the + // backup was taken and the current version. + int numSplitPerms = splitPerms.size(); + for (int i = 0; i < numSplitPerms; i++) { + SplitPermissionInfo splitPerm = splitPerms.get(i); + if (backupPlatformVersion < splitPerm.getTargetSdk() + && permName.equals(splitPerm.getSplitPermission())) { + expandedPermissions.addAll(splitPerm.getNewPermissions()); + } + } + + ArrayList parsedPermissions = new ArrayList<>( + expandedPermissions.size()); + int numExpandedPerms = expandedPermissions.size(); + for (int i = 0; i < numExpandedPerms; i++) { + parsedPermissions.add(new BackupPermissionState(expandedPermissions.get(i), + "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED)), + "true".equals(parser.getAttributeValue(null, ATTR_USER_SET)), + "true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED)), + "true".equals(parser.getAttributeValue(null, ATTR_WAS_REVIEWED)))); + } + + // TODO: Implement special behavior for location + + return parsedPermissions; } /** @@ -559,10 +606,13 @@ public class BackupHelper { * Parse a package state from XML. * * @param parser The data to read + * @param context a context to use + * @param backupPlatformVersion The platform version the backup was created on * * @return The state */ - static @NonNull BackupPackageState parseFromXml(@NonNull XmlPullParser parser) + static @NonNull BackupPackageState parseFromXml(@NonNull XmlPullParser parser, + @NonNull Context context, int backupPlatformVersion) throws IOException, XmlPullParserException { String packageName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME); if (packageName == null) { @@ -578,8 +628,9 @@ public class BackupHelper { switch (parser.getName()) { case TAG_PERMISSION: try { - permissionsToRestore.add( - BackupPermissionState.parseFromXml(parser)); + permissionsToRestore.addAll( + BackupPermissionState.parseFromXml(parser, context, + backupPlatformVersion)); } catch (XmlPullParserException e) { Log.e(LOG_TAG, "Could not parse permission for " + packageName, e); -- GitLab From fb13e64edb38c78402d65816d626315ea7cc468f Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Thu, 14 Feb 2019 16:37:46 -0800 Subject: [PATCH 373/701] Do not show warning dialog when denying a denied permission. Fixes: 124468313 Test: See dialog when denying allowed permission, don't see it when denying denied permission. Change-Id: I8542c00b41d76e5c0254f5b24543866ee41cb34c --- .../ui/handheld/AppPermissionFragment.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java index 695392e5c..6e641814a 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java @@ -705,23 +705,25 @@ public class AppPermissionFragment extends SettingsWithButtonHeader { } } } else { - boolean requestToRevokeGrantedByDefault = false; + boolean showDefaultDenyDialog = false; if ((changeTarget & CHANGE_FOREGROUND) != 0 && mGroup.areRuntimePermissionsGranted()) { - requestToRevokeGrantedByDefault = mGroup.hasGrantedByDefaultPermission(); + showDefaultDenyDialog = mGroup.hasGrantedByDefaultPermission() + || !mGroup.doesSupportRuntimePermissions() + || mGroup.hasInstallToRuntimeSplit(); } if ((changeTarget & CHANGE_BACKGROUND) != 0) { if (mGroup.getBackgroundPermissions() != null && mGroup.getBackgroundPermissions().areRuntimePermissionsGranted()) { - requestToRevokeGrantedByDefault |= - mGroup.getBackgroundPermissions().hasGrantedByDefaultPermission(); + AppPermissionGroup bgPerm = mGroup.getBackgroundPermissions(); + showDefaultDenyDialog |= bgPerm.hasGrantedByDefaultPermission() + || !bgPerm.doesSupportRuntimePermissions() + || bgPerm.hasInstallToRuntimeSplit(); } } - if ((requestToRevokeGrantedByDefault || !mGroup.doesSupportRuntimePermissions() - || mGroup.hasInstallToRuntimeSplit()) - && !mHasConfirmedRevoke) { + if (showDefaultDenyDialog && !mHasConfirmedRevoke) { showDefaultDenyDialog(changeTarget); updateButtons(); return false; -- GitLab From a81a5a6fc7eaa8a179dce8bcf3fdb94989581f68 Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Fri, 8 Feb 2019 15:29:33 -0800 Subject: [PATCH 374/701] Device admin perm adjustment -> perm controller Move permission policy adjustments from on behalf of device admin to permission controller. The permission controller has a higher level view on permissions than the system server, hence advanced features are easier to implement. Test: atest --test-mapping packages/apps/PermissionController/src/com/android/packageinstaller/permission/service:presubmit Change-Id: Ic2c7de8f3fd50129e8d19ff47e83399f87da1614 Fixes: 124128308 --- AndroidManifest.xml | 1 + .../permission/model/AppPermissionGroup.java | 2 +- .../PermissionControllerServiceImpl.java | 54 +++++++++++++++++++ .../permission/service/TEST_MAPPING | 25 ++++++++- 4 files changed, 80 insertions(+), 2 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 6d401305d..e0dc1bf3e 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -14,6 +14,7 @@ + diff --git a/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java b/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java index df077f793..f26d65740 100644 --- a/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java +++ b/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java @@ -1134,7 +1134,7 @@ public final class AppPermissionGroup implements Comparable * app ops change. If this is set to {@code false} the * caller has to make sure to kill the app if needed. */ - void persistChanges(boolean mayKillBecauseOfAppOpsChange) { + public void persistChanges(boolean mayKillBecauseOfAppOpsChange) { int numPermissions = mPermissions.size(); boolean shouldKillApp = false; boolean shouldUpdateStorage = false; diff --git a/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java b/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java index 39caf0e72..cdad957af 100644 --- a/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java +++ b/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java @@ -16,6 +16,9 @@ package com.android.packageinstaller.permission.service; +import static android.app.admin.DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT; +import static android.app.admin.DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED; +import static android.app.admin.DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED; import static android.content.pm.PackageManager.GET_PERMISSIONS; import static android.permission.PermissionControllerManager.COUNT_ONLY_WHEN_GRANTED; import static android.permission.PermissionControllerManager.COUNT_WHEN_SYSTEM; @@ -503,4 +506,55 @@ public final class PermissionControllerServiceImpl extends PermissionControllerS return PermissionControllerServiceImplRoleMixin.onIsApplicationQualifiedForRole(roleName, packageName, this); } + + @Override + public boolean onSetRuntimePermissionGrantStateByDeviceAdmin(@NonNull String callerPackageName, + @NonNull String packageName, @NonNull String unexpandedPermission, int grantState) { + PackageInfo callerPkgInfo = getPkgInfo(callerPackageName); + if (callerPkgInfo == null) { + Log.w(LOG_TAG, "Cannot fix " + unexpandedPermission + " as admin " + + callerPackageName + " cannot be found"); + return false; + } + + PackageInfo pkgInfo = getPkgInfo(packageName); + if (pkgInfo == null) { + Log.w(LOG_TAG, "Cannot fix " + unexpandedPermission + " as " + packageName + + " cannot be found"); + return false; + } + + ArrayList expandedPermissions = addSplitPermissions( + Collections.singletonList(unexpandedPermission), + callerPkgInfo.applicationInfo.targetSdkVersion); + + int numPerms = expandedPermissions.size(); + for (int i = 0; i < numPerms; i++) { + String perm = expandedPermissions.get(i); + AppPermissionGroup group = AppPermissionGroup.create(this, pkgInfo, perm, true); + if (group == null || group.isSystemFixed()) { + continue; + } + + switch (grantState) { + case PERMISSION_GRANT_STATE_GRANTED: + group.getPermission(perm).setPolicyFixed(true); + group.grantRuntimePermissions(false, new String[]{perm}); + break; + case PERMISSION_GRANT_STATE_DENIED: + group.getPermission(perm).setPolicyFixed(true); + group.revokeRuntimePermissions(false, new String[]{perm}); + break; + case PERMISSION_GRANT_STATE_DEFAULT: + group.getPermission(perm).setPolicyFixed(false); + break; + default: + return false; + } + + group.persistChanges(true); + } + + return true; + } } diff --git a/src/com/android/packageinstaller/permission/service/TEST_MAPPING b/src/com/android/packageinstaller/permission/service/TEST_MAPPING index c11483969..ff5740e2d 100644 --- a/src/com/android/packageinstaller/permission/service/TEST_MAPPING +++ b/src/com/android/packageinstaller/permission/service/TEST_MAPPING @@ -18,6 +18,29 @@ "include-filter": "android.backup.cts.PermissionTest" } ] + }, + { + "name": "CtsDevicePolicyManagerTestCases", + "options": [ + { + "include-filter": "com.android.cts.devicepolicy.MixedManagedProfileOwnerTest#testPermissionGrant" + }, + { + "include-filter": "com.android.cts.devicepolicy.MixedManagedProfileOwnerTest#testPermissionPolicy" + }, + { + "include-filter": "com.android.cts.devicepolicy.MixedManagedProfileOwnerTest#testPermissionMixedPolicies" + }, + { + "include-filter": "com.android.cts.devicepolicy.MixedManagedProfileOwnerTest#testPermissionAppUpdate" + }, + { + "include-filter": "com.android.cts.devicepolicy.MixedManagedProfileOwnerTest#testPermissionGrantPreMApp" + }, + { + "include-filter": "com.android.cts.devicepolicy.MixedManagedProfileOwnerTestApi25#testPermissionGrantPreMApp" + } + ] } ] -} +} \ No newline at end of file -- GitLab From 7c2ca01a114708d7000cf277d21c3da9f8482622 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Fri, 15 Feb 2019 13:44:11 -0800 Subject: [PATCH 375/701] Optimize Permissions Hub by not loading non-platform permission groups. Added a flag when loading permission groups that controls whether or not to load non-platform permission groups. Some uses, including Permissions Hub, only use the platform permissions, so we can save time by ignoring the others. On my dev phone this reduces the Permissions Hub loading time by about a quarter. Bug: 124052170 Test: Load Permissions Hub, see it is faster. Test: Ensure App Permissions and search indexing still work. Change-Id: I1489d227342e115464363cb78e914ce78ad88d5e --- .../permission/model/PermissionGroups.java | 36 +++++++++++++++---- .../permission/model/PermissionUsages.java | 17 ++++++--- .../PermissionControllerServiceImpl.java | 2 +- .../handheld/AppPermissionUsageFragment.java | 2 +- .../handheld/ManagePermissionsFragment.java | 2 +- .../ManageStandardPermissionsFragment.java | 2 +- .../ui/handheld/PermissionUsageFragment.java | 3 +- .../television/ManagePermissionsFragment.java | 2 +- 8 files changed, 48 insertions(+), 18 deletions(-) diff --git a/src/com/android/packageinstaller/permission/model/PermissionGroups.java b/src/com/android/packageinstaller/permission/model/PermissionGroups.java index 3da6cafac..7c3f3a91e 100644 --- a/src/com/android/packageinstaller/permission/model/PermissionGroups.java +++ b/src/com/android/packageinstaller/permission/model/PermissionGroups.java @@ -55,16 +55,19 @@ public final class PermissionGroups implements LoaderCallbacks> onCreateLoader(int id, Bundle args) { - return new PermissionsLoader(mContext, mGetAppUiInfo); + return new PermissionsLoader(mContext, mGetAppUiInfo, mGetNonPlatformPermissions); } @Override @@ -135,12 +138,15 @@ public final class PermissionGroups implements LoaderCallbacks getAllPermissionGroups(@NonNull Context context, - @Nullable Supplier isCanceled, boolean getAppUiInfo) { - return getPermissionGroups(context, isCanceled, getAppUiInfo, null, null); + @Nullable Supplier isCanceled, boolean getAppUiInfo, + boolean getNonPlatformPermissions) { + return getPermissionGroups(context, isCanceled, getAppUiInfo, getNonPlatformPermissions, + null, null); } /** @@ -149,6 +155,7 @@ public final class PermissionGroups implements LoaderCallbacks getPermissionGroups(@NonNull Context context, @Nullable Supplier isCanceled, boolean getAppUiInfo, - @Nullable String groupName, @Nullable String packageName) { + boolean getNonPlatformPermissions, @Nullable String groupName, + @Nullable String packageName) { ArraySet launcherPkgs = Utils.getLauncherPackages(context); PermissionApps.PmCache pmCache = new PermissionApps.PmCache( context.getPackageManager()); @@ -175,6 +183,11 @@ public final class PermissionGroups implements LoaderCallbacks groupPermissions; try { @@ -248,6 +261,12 @@ public final class PermissionGroups implements LoaderCallbacks> implements PackageManager.OnPermissionsChangedListener { private final boolean mGetAppUiInfo; + private final boolean mGetNonPlatformPermissions; - PermissionsLoader(Context context, boolean getAppUiInfo) { + PermissionsLoader(Context context, boolean getAppUiInfo, + boolean getNonPlatformPermissions) { super(context); mGetAppUiInfo = getAppUiInfo; + mGetNonPlatformPermissions = getNonPlatformPermissions; } @Override @@ -323,7 +345,7 @@ public final class PermissionGroups implements LoaderCallbacks loadInBackground() { return getAllPermissionGroups(getContext(), this::isLoadInBackgroundCanceled, - mGetAppUiInfo); + mGetAppUiInfo, mGetNonPlatformPermissions); } @Override diff --git a/src/com/android/packageinstaller/permission/model/PermissionUsages.java b/src/com/android/packageinstaller/permission/model/PermissionUsages.java index 73331c300..d34219582 100644 --- a/src/com/android/packageinstaller/permission/model/PermissionUsages.java +++ b/src/com/android/packageinstaller/permission/model/PermissionUsages.java @@ -63,6 +63,8 @@ public final class PermissionUsages implements LoaderCallbacks usages = loader.loadInBackground(); @@ -166,6 +171,7 @@ public final class PermissionUsages implements LoaderCallbacks loadInBackground() { final List groups = PermissionGroups.getPermissionGroups( getContext(), this::isLoadInBackgroundCanceled, mGetUiInfo, - mFilterPermissionGroup, mFilterPackageName); + mGetNonPlatformPermissions, mFilterPermissionGroup, mFilterPackageName); if (!Utils.isPermissionsHubEnabled()) { return Collections.emptyList(); } diff --git a/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java b/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java index f24049bd1..f7e1f5fce 100644 --- a/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java +++ b/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java @@ -438,7 +438,7 @@ public final class PermissionControllerServiceImpl extends PermissionControllerS long filterTimeBeginMillis = Math.max(System.currentTimeMillis() - numMillis, 0); usages.load(null, null, filterTimeBeginMillis, Long.MAX_VALUE, PermissionUsages.USAGE_FLAG_LAST | PermissionUsages.USAGE_FLAG_HISTORICAL, null, - false, null, true); + false, false, null, true); List appPermissionUsages = usages.getUsages(); int numApps = appPermissionUsages.size(); diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java index 1fd678ff0..265e8b872 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java @@ -275,6 +275,6 @@ public class AppPermissionUsageFragment extends SettingsWithButtonHeader impleme mPermissionUsages.load(mAppInfo.uid, mPackageName, null, beginTimeMillis, Long.MAX_VALUE, PermissionUsages.USAGE_FLAG_LAST | PermissionUsages.USAGE_FLAG_HISTORICAL, getActivity().getLoaderManager(), - true, this::updateUi, false); + true, false, this::updateUi, false); } } diff --git a/src/com/android/packageinstaller/permission/ui/handheld/ManagePermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/ManagePermissionsFragment.java index 307312479..0bba6cdfb 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/ManagePermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/ManagePermissionsFragment.java @@ -60,7 +60,7 @@ abstract class ManagePermissionsFragment extends PermissionsFrameFragment } mPermissions = new PermissionGroups(getContext(), getActivity().getLoaderManager(), this, - false); + false, true); mCollator = Collator.getInstance( getContext().getResources().getConfiguration().getLocales().get(0)); } diff --git a/src/com/android/packageinstaller/permission/ui/handheld/ManageStandardPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/ManageStandardPermissionsFragment.java index 7e70b8cf7..fd527e228 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/ManageStandardPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/ManageStandardPermissionsFragment.java @@ -109,7 +109,7 @@ public final class ManageStandardPermissionsFragment extends ManagePermissionsFr Long.MAX_VALUE, PermissionUsages.USAGE_FLAG_LAST | PermissionUsages.USAGE_FLAG_HISTORICAL, getActivity().getLoaderManager(), - false, this::updateRecentlyUsedWidget, false); + false, false, this::updateRecentlyUsedWidget, false); return root; } diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java index 7b960362a..71fed4c69 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java @@ -528,7 +528,8 @@ public class PermissionUsageFragment extends SettingsWithButtonHeader implements mPermissionUsages.load(null /*filterPackageName*/, null /*filterPermissionGroup*/, filterTimeBeginMillis, Long.MAX_VALUE, PermissionUsages.USAGE_FLAG_LAST | PermissionUsages.USAGE_FLAG_HISTORICAL, getActivity().getLoaderManager(), - false /*getUiInfo*/, this /*callback*/, false /*sync*/); + false /*getUiInfo*/, false /*getNonPlatformPermissions*/, this /*callback*/, + false /*sync*/); if (mFinishedInitialLoad) { setProgressBarVisible(true); } diff --git a/src/com/android/packageinstaller/permission/ui/television/ManagePermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/television/ManagePermissionsFragment.java index 09800534c..d8a975b16 100644 --- a/src/com/android/packageinstaller/permission/ui/television/ManagePermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/television/ManagePermissionsFragment.java @@ -66,7 +66,7 @@ public final class ManagePermissionsFragment extends SettingsWithHeader ab.setDisplayHomeAsUpEnabled(true); } mLauncherPkgs = Utils.getLauncherPackages(getContext()); - mPermissions = new PermissionGroups(getContext(), getLoaderManager(), this, false); + mPermissions = new PermissionGroups(getContext(), getLoaderManager(), this, false, true); } @Override -- GitLab From 836f19df0055a6ad9fbba6d2fc5172b4a6017dfb Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Fri, 15 Feb 2019 18:42:51 -0800 Subject: [PATCH 376/701] Add more logging when a package don't qualify for role. I was debugging assistant fallback for secondary users, and had a hard time figuring out why assistant lost the role. Adding more log will help us know why things were happening in the future. Bug: 124452117 Test: build Change-Id: I2f21aff2178a4b19df7f9188cc07d9949212cf54 --- .../role/model/AssistantRoleBehavior.java | 13 ++++++++++++- .../role/model/ExclusiveDefaultHolderMixin.java | 2 ++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/com/android/packageinstaller/role/model/AssistantRoleBehavior.java b/src/com/android/packageinstaller/role/model/AssistantRoleBehavior.java index ec8db6391..b58fda9fc 100644 --- a/src/com/android/packageinstaller/role/model/AssistantRoleBehavior.java +++ b/src/com/android/packageinstaller/role/model/AssistantRoleBehavior.java @@ -29,6 +29,7 @@ import android.provider.Settings; import android.service.voice.VoiceInteractionService; import android.util.ArraySet; import android.util.AttributeSet; +import android.util.Log; import android.util.Xml; import androidx.annotation.NonNull; @@ -49,6 +50,8 @@ import java.util.Set; */ public class AssistantRoleBehavior implements RoleBehavior { + private static final String LOG_TAG = AssistantRoleBehavior.class.getSimpleName(); + private static final Intent ASSIST_SERVICE_PROBE = new Intent(VoiceInteractionService.SERVICE_INTERFACE); private static final Intent ASSIST_ACTIVITY_PROBE = new Intent(Intent.ACTION_ASSIST); @@ -131,8 +134,16 @@ public class AssistantRoleBehavior implements RoleBehavior { } Intent pkgActivityProbe = new Intent(ASSIST_ACTIVITY_PROBE).setPackage(packageName); - return !pm.queryIntentActivities(pkgActivityProbe, + boolean hasAssistantActivity = !pm.queryIntentActivities(pkgActivityProbe, PackageManager.MATCH_DEFAULT_ONLY).isEmpty(); + + if (!hasAssistantActivity) { + Log.w(LOG_TAG, "Package " + packageName + " not qualified for " + role.getName() + + " due to " + (services.isEmpty() ? "missing service" + : "service without qualifying metadata") + " and missing activity"); + } + + return hasAssistantActivity; } private boolean isAssistantVoiceInteractionService(@NonNull PackageManager pm, diff --git a/src/com/android/packageinstaller/role/model/ExclusiveDefaultHolderMixin.java b/src/com/android/packageinstaller/role/model/ExclusiveDefaultHolderMixin.java index aeaf102d3..e9f8bbff4 100644 --- a/src/com/android/packageinstaller/role/model/ExclusiveDefaultHolderMixin.java +++ b/src/com/android/packageinstaller/role/model/ExclusiveDefaultHolderMixin.java @@ -79,6 +79,8 @@ public class ExclusiveDefaultHolderMixin { } if (!role.isPackageQualified(packageName, context)) { + Log.w(LOG_TAG, "Default holder does not qualify for the role, config: " + resourceName + + ", package: " + packageName); return null; } return packageName; -- GitLab From 200dc55bf094b9a20ae0517ab0b55627bb431972 Mon Sep 17 00:00:00 2001 From: Svet Ganov Date: Tue, 22 Jan 2019 20:44:16 -0800 Subject: [PATCH 377/701] Add request object for querying historical ops - PermissionController Test: atest CtsAppOpsTestCases bug:123253745 Change-Id: I3cff17fe08ad361488a21d14d6a523f0c4c3f08c --- .../permission/model/PermissionUsages.java | 11 ++++++++--- .../permission/service/LocationAccessCheck.java | 11 ++++++++--- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/com/android/packageinstaller/permission/model/PermissionUsages.java b/src/com/android/packageinstaller/permission/model/PermissionUsages.java index d34219582..08d19e9f5 100644 --- a/src/com/android/packageinstaller/permission/model/PermissionUsages.java +++ b/src/com/android/packageinstaller/permission/model/PermissionUsages.java @@ -18,6 +18,7 @@ package com.android.packageinstaller.permission.model; import android.app.AppOpsManager; import android.app.AppOpsManager.HistoricalOps; +import android.app.AppOpsManager.HistoricalOpsRequest; import android.app.AppOpsManager.HistoricalPackageOps; import android.app.AppOpsManager.HistoricalUidOps; import android.app.AppOpsManager.PackageOps; @@ -289,9 +290,13 @@ public final class PermissionUsages implements LoaderCallbacks historicalOpsRef = new AtomicReference<>(); final CountDownLatch latch = new CountDownLatch(1); - appOpsManager.getHistoricalOps(mFilterUid, - mFilterPackageName, opNamesArray, mFilterBeginTimeMillis, - mFilterEndTimeMillis, Runnable::run, + final HistoricalOpsRequest request = new HistoricalOpsRequest.Builder( + mFilterBeginTimeMillis, mFilterEndTimeMillis) + .setUid(mFilterUid) + .setPackageName(mFilterPackageName) + .setOpNames(new ArrayList<>(opNames)) + .build(); + appOpsManager.getHistoricalOps(request, Runnable::run, (HistoricalOps ops) -> { historicalOpsRef.set(ops); latch.countDown(); diff --git a/src/com/android/packageinstaller/permission/service/LocationAccessCheck.java b/src/com/android/packageinstaller/permission/service/LocationAccessCheck.java index dcfc9cf40..11bf295fc 100644 --- a/src/com/android/packageinstaller/permission/service/LocationAccessCheck.java +++ b/src/com/android/packageinstaller/permission/service/LocationAccessCheck.java @@ -33,7 +33,6 @@ import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.content.pm.PackageManager.GET_PERMISSIONS; import static android.graphics.Bitmap.Config.ARGB_8888; import static android.graphics.Bitmap.createBitmap; -import static android.os.Process.INVALID_UID; import static android.os.UserHandle.getUserHandleForUid; import static android.os.UserHandle.myUserId; import static android.provider.Settings.Secure.LOCATION_ACCESS_CHECK_DELAY_MILLIS; @@ -59,6 +58,7 @@ import static java.util.concurrent.TimeUnit.MINUTES; import android.app.AppOpsManager; import android.app.AppOpsManager.HistoricalOps; +import android.app.AppOpsManager.HistoricalOpsRequest; import android.app.AppOpsManager.HistoricalPackageOps; import android.app.Notification; import android.app.NotificationChannel; @@ -95,6 +95,7 @@ import androidx.core.util.Preconditions; import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.ui.AppPermissionActivity; +import com.android.packageinstaller.permission.utils.CollectionUtils; import com.android.permissioncontroller.R; import java.io.BufferedReader; @@ -103,6 +104,7 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; +import java.time.Instant; import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -363,9 +365,12 @@ public class LocationAccessCheck { return; } + HistoricalOpsRequest request = new HistoricalOpsRequest.Builder( + Instant.EPOCH.toEpochMilli(), Long.MAX_VALUE) + .setOpNames(CollectionUtils.singletonOrEmpty(OPSTR_FINE_LOCATION)) + .build(); HistoricalOps[] ops = new HistoricalOps[1]; - mAppOpsManager.getHistoricalOps(INVALID_UID, null, - new String[]{OPSTR_FINE_LOCATION}, 0, Long.MAX_VALUE, + mAppOpsManager.getHistoricalOps(request, mContext.getMainExecutor(), (h) -> { synchronized (ops) { ops[0] = h; -- GitLab From a5acd0e953452d9563748f1c16d3a2090bc86da5 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Thu, 14 Feb 2019 15:55:11 -0800 Subject: [PATCH 378/701] Show usage duration in Permissions Hub. In addition to showing the number of accesses we can also show duration (for permissions where that makes sense). I also fixed the strings to correctly say "access" instead of "accesses" when there is only one access. Test: Open Permissions Hub, see singular and plural strings with and without duration. Change-Id: I9330a257a06eef0c9ec3fe0bdc63e724956afd57 --- res/values/strings.xml | 22 ++++++++++- .../handheld/PermissionControlPreference.java | 39 ++++++++++++++++--- .../permission/utils/Utils.java | 7 ++-- 3 files changed, 56 insertions(+), 12 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 73c65fc65..4505be48c 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -256,10 +256,28 @@ Permissions usage - Last access: %1$s\n%2$s accesses + + Last access: %1$s\n%2$s access + Last access: %1$s\n%2$s accesses + - Last access: %1$s\n%2$s accesses (%3$s in background) + + Last access: %1$s\n%2$s access (%3$s in background) + Last access: %1$s\n%2$s accesses (%3$s in background) + + + + + Last access: %1$s\n%2$s access\nDuration: %3$s + Last access: %1$s\n%2$s accesses\nDuration: %3$s + + + + + Last access: %1$s\n%2$s access (%3$s in background)\nDuration: %3$s + Last access: %1$s\n%2$s accesses (%3$s in background)\nDuration: %3$s + Any permission diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionControlPreference.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionControlPreference.java index 5dc9411e8..c7b7ff86e 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionControlPreference.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionControlPreference.java @@ -16,6 +16,9 @@ package com.android.packageinstaller.permission.ui.handheld; +import static android.Manifest.permission_group.CAMERA; +import static android.Manifest.permission_group.MICROPHONE; + import android.content.Context; import android.content.Intent; import android.graphics.drawable.Drawable; @@ -34,6 +37,7 @@ import androidx.preference.PreferenceViewHolder; import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.model.AppPermissionUsage.GroupUsage; import com.android.packageinstaller.permission.ui.AppPermissionActivity; +import com.android.packageinstaller.permission.utils.Utils; import com.android.permissioncontroller.R; import java.util.List; @@ -121,13 +125,36 @@ public class PermissionControlPreference extends Preference { * @param accessTimeStr the string representing the last access time */ public void setUsageSummary(@NonNull GroupUsage groupUsage, @NonNull String accessTimeStr) { - if (groupUsage.getBackgroundAccessCount() == 0) { - setSummary(mContext.getString(R.string.permission_usage_summary, accessTimeStr, - groupUsage.getForegroundAccessCount())); + long backgroundAccessCount = groupUsage.getBackgroundAccessCount(); + long duration = 0; + String groupName = groupUsage.getGroup().getName(); + if (groupName.equals(CAMERA) || groupName.equals(MICROPHONE)) { + duration = groupUsage.getAccessDuration(); + } + if (backgroundAccessCount == 0) { + long numForegroundAccesses = groupUsage.getForegroundAccessCount(); + if (duration == 0) { + setSummary(mContext.getResources().getQuantityString( + R.plurals.permission_usage_summary, (int) numForegroundAccesses, + accessTimeStr, numForegroundAccesses)); + } else { + setSummary(mContext.getResources().getQuantityString( + R.plurals.permission_usage_summary_duration, (int) numForegroundAccesses, + accessTimeStr, numForegroundAccesses, + Utils.getUsageDurationString(mContext, groupUsage))); + } } else { - setSummary( - mContext.getString(R.string.permission_usage_summary_background, accessTimeStr, - groupUsage.getAccessCount(), groupUsage.getBackgroundAccessCount())); + long numAccesses = groupUsage.getAccessCount(); + if (duration == 0) { + setSummary(mContext.getResources().getQuantityString( + R.plurals.permission_usage_summary_background, (int) numAccesses, + accessTimeStr, numAccesses, backgroundAccessCount)); + } else { + setSummary(mContext.getResources().getQuantityString( + R.plurals.permission_usage_summary_background_duration, (int) numAccesses, + accessTimeStr, numAccesses, backgroundAccessCount, + Utils.getUsageDurationString(mContext, groupUsage))); + } } } diff --git a/src/com/android/packageinstaller/permission/utils/Utils.java b/src/com/android/packageinstaller/permission/utils/Utils.java index 2fa9d1503..d2a8735d2 100644 --- a/src/com/android/packageinstaller/permission/utils/Utils.java +++ b/src/com/android/packageinstaller/permission/utils/Utils.java @@ -573,16 +573,15 @@ public final class Utils { /** * Build a string representing the duration of a permission usage. * - * @return a string representing the amount of time since this app's most recent permission - * usage or null if there are no usages. + * @return a string representing the duration of this app's usage or null if there are no + * usages. */ public static @Nullable String getUsageDurationString(@NonNull Context context, @Nullable AppPermissionUsage.GroupUsage groupUsage) { if (groupUsage == null) { return null; } - return getTimeDiffStr(context, System.currentTimeMillis() - - groupUsage.getAccessDuration()); + return getTimeDiffStr(context, groupUsage.getAccessDuration()); } /** -- GitLab From 8f669af93aee020cf2aefbb9d240ae6fc04c9da7 Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Tue, 19 Feb 2019 13:01:30 -0800 Subject: [PATCH 379/701] Add visibility config for assistant, home and emergency role. Default assistant, home and emergency could be hidden from users, so keep this ability when we migrate to roles. Bug: 124452117 Bug: 124260975 Test: manual Change-Id: I03265d3f19950b603f74f33b18492ede868e6e49 --- .../role/model/AssistantRoleBehavior.java | 6 +++ .../role/model/EmergencyRoleBehavior.java | 6 +++ .../model/ExclusiveDefaultHolderMixin.java | 8 ++- .../role/model/HomeRoleBehavior.java | 6 +++ .../packageinstaller/role/model/Role.java | 15 ++++++ .../role/model/RoleBehavior.java | 8 +++ .../role/model/VisibilityMixin.java | 53 +++++++++++++++++++ 7 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 src/com/android/packageinstaller/role/model/VisibilityMixin.java diff --git a/src/com/android/packageinstaller/role/model/AssistantRoleBehavior.java b/src/com/android/packageinstaller/role/model/AssistantRoleBehavior.java index b58fda9fc..92191bafa 100644 --- a/src/com/android/packageinstaller/role/model/AssistantRoleBehavior.java +++ b/src/com/android/packageinstaller/role/model/AssistantRoleBehavior.java @@ -70,6 +70,12 @@ public class AssistantRoleBehavior implements RoleBehavior { context); } + @Override + public boolean isVisibleAsUser(@NonNull Role role, @NonNull UserHandle user, + @NonNull Context context) { + return VisibilityMixin.isVisible("config_showDefaultAssistant", context); + } + @Nullable @Override public Intent getManageIntentAsUser(@NonNull Role role, @NonNull UserHandle user, diff --git a/src/com/android/packageinstaller/role/model/EmergencyRoleBehavior.java b/src/com/android/packageinstaller/role/model/EmergencyRoleBehavior.java index b4220a356..0f5875de2 100644 --- a/src/com/android/packageinstaller/role/model/EmergencyRoleBehavior.java +++ b/src/com/android/packageinstaller/role/model/EmergencyRoleBehavior.java @@ -69,6 +69,12 @@ public class EmergencyRoleBehavior implements RoleBehavior { return fallbackPackageInfo != null ? fallbackPackageInfo.packageName : null; } + @Override + public boolean isVisibleAsUser(@NonNull Role role, @NonNull UserHandle user, + @NonNull Context context) { + return VisibilityMixin.isVisible("config_showDefaultEmergency", context); + } + @Nullable @Override public CharSequence getConfirmationMessage(@NonNull Role role, @NonNull String packageName, diff --git a/src/com/android/packageinstaller/role/model/ExclusiveDefaultHolderMixin.java b/src/com/android/packageinstaller/role/model/ExclusiveDefaultHolderMixin.java index e9f8bbff4..86073c850 100644 --- a/src/com/android/packageinstaller/role/model/ExclusiveDefaultHolderMixin.java +++ b/src/com/android/packageinstaller/role/model/ExclusiveDefaultHolderMixin.java @@ -61,7 +61,13 @@ public class ExclusiveDefaultHolderMixin { Log.w(LOG_TAG, "Cannot find resource for default holder: " + resourceName); return null; } - String packageName = resources.getString(resourceId); + String packageName; + try { + packageName = resources.getString(resourceId); + } catch (Resources.NotFoundException e) { + Log.w(LOG_TAG, "Cannot get resource for default holder: " + resourceName, e); + return null; + } if (TextUtils.isEmpty(packageName)) { return null; } diff --git a/src/com/android/packageinstaller/role/model/HomeRoleBehavior.java b/src/com/android/packageinstaller/role/model/HomeRoleBehavior.java index 87eb48e4f..38b85d55f 100644 --- a/src/com/android/packageinstaller/role/model/HomeRoleBehavior.java +++ b/src/com/android/packageinstaller/role/model/HomeRoleBehavior.java @@ -84,6 +84,12 @@ public class HomeRoleBehavior implements RoleBehavior { return packageName; } + @Override + public boolean isVisibleAsUser(@NonNull Role role, @NonNull UserHandle user, + @NonNull Context context) { + return VisibilityMixin.isVisible("config_showDefaultHome", context); + } + @Override public void prepareApplicationPreferenceAsUser(@NonNull Role role, @NonNull Preference preference, @NonNull ApplicationInfo applicationInfo, diff --git a/src/com/android/packageinstaller/role/model/Role.java b/src/com/android/packageinstaller/role/model/Role.java index 1ae8b1d15..d2c32b811 100644 --- a/src/com/android/packageinstaller/role/model/Role.java +++ b/src/com/android/packageinstaller/role/model/Role.java @@ -246,6 +246,21 @@ public class Role { return null; } + /** + * Check whether this role should be visible to user. + * + * @param user the user to check for + * @param context the {@code Context} to retrieve system services + * + * @return whether this role should be visible to user + */ + public boolean isVisibleAsUser(@NonNull UserHandle user, @NonNull Context context) { + if (mBehavior != null) { + return mBehavior.isVisibleAsUser(this, user, context); + } + return true; + } + /** * Get the {@link Intent} to manage this role, or {@code null} to use the default UI. * diff --git a/src/com/android/packageinstaller/role/model/RoleBehavior.java b/src/com/android/packageinstaller/role/model/RoleBehavior.java index d0f89c348..07362c11a 100644 --- a/src/com/android/packageinstaller/role/model/RoleBehavior.java +++ b/src/com/android/packageinstaller/role/model/RoleBehavior.java @@ -57,6 +57,14 @@ public interface RoleBehavior { return null; } + /** + * @see Role#isVisibleAsUser(UserHandle, Context) + */ + default boolean isVisibleAsUser(@NonNull Role role, @NonNull UserHandle user, + @NonNull Context context) { + return true; + } + /** * @see Role#getManageIntentAsUser(UserHandle, Context) */ diff --git a/src/com/android/packageinstaller/role/model/VisibilityMixin.java b/src/com/android/packageinstaller/role/model/VisibilityMixin.java new file mode 100644 index 000000000..5096c3144 --- /dev/null +++ b/src/com/android/packageinstaller/role/model/VisibilityMixin.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2019 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.packageinstaller.role.model; + +import android.content.Context; +import android.content.res.Resources; +import android.os.UserHandle; +import android.util.Log; + +import androidx.annotation.NonNull; + +/** + * Mixin for {@link RoleBehavior#getDefaultHolders(Role, Context)} that returns a single default + * role holder from the corresponding string resource. + */ +public class VisibilityMixin { + + private static final String LOG_TAG = VisibilityMixin.class.getSimpleName(); + + private VisibilityMixin() {} + + /** + * @see Role#isVisibleAsUser(UserHandle, Context) + */ + public static boolean isVisible(@NonNull String resourceName, @NonNull Context context) { + Resources resources = context.getResources(); + int resourceId = resources.getIdentifier(resourceName, "boolean", "android"); + if (resourceId == 0) { + Log.w(LOG_TAG, "Cannot find resource for visibility: " + resourceName); + return true; + } + try { + return resources.getBoolean(resourceId); + } catch (Resources.NotFoundException e) { + Log.w(LOG_TAG, "Cannot get resource for visibility: " + resourceName, e); + return true; + } + } +} -- GitLab From 79f155158c4a7840506a377213fe84fff2e291f5 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Tue, 19 Feb 2019 13:30:43 -0800 Subject: [PATCH 380/701] Add a never accessed subtitle to permission screens. Modify PermissionAppsFragment and AppPermissionsFragment to print out a string when a permission was never accessed. Fixes: 124768207 Test: View screens. Change-Id: I34afda527e0ae2366a6f183ac2d20fea208bd2ac --- res/values/strings.xml | 3 +++ .../permission/ui/handheld/AppPermissionsFragment.java | 4 ++++ .../permission/ui/handheld/PermissionAppsFragment.java | 2 ++ 3 files changed, 9 insertions(+) diff --git a/res/values/strings.xml b/res/values/strings.xml index 73c65fc65..7f99341f5 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -390,6 +390,9 @@ Last access: %1$s + + Never accessed + Allowed diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java index ed115bc1a..bd6bf6ba9 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java @@ -224,6 +224,10 @@ public final class AppPermissionsFragment extends SettingsWithButtonHeader { lastAccessStr)); } else { preference.setGroupSummary(group); + if (preference.getSummary().length() == 0) { + preference.setSummary( + context.getString(R.string.app_permission_never_accessed_summary)); + } } if (isPlatform) { diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java index ef874b17a..b736295d7 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java @@ -369,6 +369,8 @@ public final class PermissionAppsFragment extends PermissionsFrameFragment imple if (lastAccessStr != null && !group.getLabel().equals("Storage")) { pref.setSummary(context.getString(R.string.app_permission_most_recent_summary, lastAccessStr)); + } else { + pref.setSummary(context.getString(R.string.app_permission_never_accessed_summary)); } } -- GitLab From 4367bdc7089d421a8dbd210290ce90a105f11f93 Mon Sep 17 00:00:00 2001 From: Dan Shi Date: Wed, 20 Feb 2019 09:34:35 -0800 Subject: [PATCH 381/701] Reduce CtsRoleTestCases to postsubmit as the test becomes too flaky Bug: 123376916 Test: none Change-Id: I4340519e3eabdc408855e068cd9e2a76c15b59cb --- res/xml/TEST_MAPPING | 2 +- src/com/android/packageinstaller/role/TEST_MAPPING | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/res/xml/TEST_MAPPING b/res/xml/TEST_MAPPING index f6ee7e82e..97a0415a4 100644 --- a/res/xml/TEST_MAPPING +++ b/res/xml/TEST_MAPPING @@ -1,5 +1,5 @@ { - "presubmit": [ + "postsubmit": [ { "name": "CtsRoleTestCases" } diff --git a/src/com/android/packageinstaller/role/TEST_MAPPING b/src/com/android/packageinstaller/role/TEST_MAPPING index f6ee7e82e..97a0415a4 100644 --- a/src/com/android/packageinstaller/role/TEST_MAPPING +++ b/src/com/android/packageinstaller/role/TEST_MAPPING @@ -1,5 +1,5 @@ { - "presubmit": [ + "postsubmit": [ { "name": "CtsRoleTestCases" } -- GitLab From 93beea5ce5bd8e1a8e23f107d53529836b2b78ed Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Wed, 20 Feb 2019 10:33:33 -0800 Subject: [PATCH 382/701] Don't show roles that are not visible. Bug: 124452117 Bug: 124260975 Test: manual Change-Id: If1135d1e818ef9687c333146af57a139876bf879 --- .../android/packageinstaller/role/ui/RoleListLiveData.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/com/android/packageinstaller/role/ui/RoleListLiveData.java b/src/com/android/packageinstaller/role/ui/RoleListLiveData.java index 88c8f3c2f..844c2cba9 100644 --- a/src/com/android/packageinstaller/role/ui/RoleListLiveData.java +++ b/src/com/android/packageinstaller/role/ui/RoleListLiveData.java @@ -95,6 +95,10 @@ public class RoleListLiveData extends AsyncTaskLiveData> continue; } + if (!role.isVisibleAsUser(mUser, mContext)) { + continue; + } + if (mExclusive && role.getQualifyingPackagesAsUser(mUser, mContext).isEmpty()) { continue; } -- GitLab From fd88684142df818c9846fd697e742b3bea4dd375 Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Wed, 20 Feb 2019 11:41:11 -0800 Subject: [PATCH 383/701] Explicitly disallow instant app when querying for browsers. Because we are passing MATCH_ALL for getting available browsers. Bug: 124452117 Test: build Change-Id: I2d6c3fed607a03e9cc5681f2db948d1a513073d0 --- .../packageinstaller/role/model/BrowserRoleBehavior.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/com/android/packageinstaller/role/model/BrowserRoleBehavior.java b/src/com/android/packageinstaller/role/model/BrowserRoleBehavior.java index 94a104d48..ed503a769 100644 --- a/src/com/android/packageinstaller/role/model/BrowserRoleBehavior.java +++ b/src/com/android/packageinstaller/role/model/BrowserRoleBehavior.java @@ -100,7 +100,8 @@ public class BrowserRoleBehavior implements RoleBehavior { ResolveInfo resolveInfo = resolveInfos.get(i); if (!resolveInfo.handleAllWebDataURI || !resolveInfo.activityInfo.enabled - || !resolveInfo.activityInfo.applicationInfo.enabled) { + || !resolveInfo.activityInfo.applicationInfo.enabled + || resolveInfo.activityInfo.applicationInfo.isInstantApp()) { continue; } packageNames.add(resolveInfo.activityInfo.packageName); -- GitLab From d87a21dd7b769f1cc1c5c0e36e1394df831a997e Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Wed, 20 Feb 2019 13:08:41 -0800 Subject: [PATCH 384/701] Ensure AppPermissionsFragment starts scrolled to the top. Without this, opening AppPermissionsFragment for an app with many permissions starts below the header, so it's not visually obvious which app is open. This fixes that. Test: Open AppPermissionsFragment and see header at top. Test: Open other permissions screens and see they work. Change-Id: I169e5b02c92b4af031a9d35d22998cf797430a63 --- .../permission/ui/handheld/PermissionsFrameFragment.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionsFrameFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionsFrameFragment.java index 4411f0d89..c2d7ea40c 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionsFrameFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionsFrameFragment.java @@ -88,6 +88,7 @@ public abstract class PermissionsFrameFragment extends PreferenceFragmentCompat mProgressHeader = rootView.requireViewById(R.id.progress_bar_animation); mProgressView = rootView.requireViewById(R.id.progress_bar_background); setProgressBarVisible(false); + getListView().setFocusable(false); return rootView; } -- GitLab From 86d8198c04ded6832efcde6c25d315b292d047fd Mon Sep 17 00:00:00 2001 From: Evan Severson Date: Wed, 20 Feb 2019 14:38:58 -0800 Subject: [PATCH 385/701] Add resource overlay enforcement Test: Experimented with overlays Change-Id: Id996b6643816e0fc9715dbd8c00c54b1af3392bd --- res/values/overlayable.xml | 65 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 res/values/overlayable.xml diff --git a/res/values/overlayable.xml b/res/values/overlayable.xml new file mode 100644 index 000000000..25adbedcb --- /dev/null +++ b/res/values/overlayable.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- GitLab From f15df26ba695ce4aeb6afad956113d6322f84c04 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Wed, 20 Feb 2019 19:07:19 -0800 Subject: [PATCH 386/701] Import translations. DO NOT MERGE Change-Id: Ie7a9e876eeecd094dacbe0dd2305cfd206cd1546 Auto-generated-cl: translation import --- res/values-af/strings.xml | 12 +++++++++--- res/values-am/strings.xml | 12 +++++++++--- res/values-ar/strings.xml | 12 +++++++++--- res/values-as/strings.xml | 19 ++++++++++++++++--- res/values-az/strings.xml | 12 +++++++++--- res/values-b+sr+Latn/strings.xml | 12 +++++++++--- res/values-be/strings.xml | 12 +++++++++--- res/values-bg/strings.xml | 12 +++++++++--- res/values-bn/strings.xml | 19 ++++++++++++++++--- res/values-bs/strings.xml | 12 +++++++++--- res/values-ca/strings.xml | 12 +++++++++--- res/values-cs/strings.xml | 12 +++++++++--- res/values-da/strings.xml | 12 +++++++++--- res/values-de/strings.xml | 12 +++++++++--- res/values-el/strings.xml | 12 +++++++++--- res/values-en-rAU/strings.xml | 12 +++++++++--- res/values-en-rCA/strings.xml | 12 +++++++++--- res/values-en-rGB/strings.xml | 12 +++++++++--- res/values-en-rIN/strings.xml | 12 +++++++++--- res/values-en-rXC/strings.xml | 12 +++++++++--- res/values-es-rUS/strings.xml | 12 +++++++++--- res/values-es/strings.xml | 12 +++++++++--- res/values-et/strings.xml | 12 +++++++++--- res/values-eu/strings.xml | 12 +++++++++--- res/values-fa/strings.xml | 12 +++++++++--- res/values-fi/strings.xml | 12 +++++++++--- res/values-fr-rCA/strings.xml | 12 +++++++++--- res/values-fr/strings.xml | 12 +++++++++--- res/values-gl/strings.xml | 14 ++++++++++---- res/values-gu/strings.xml | 12 +++++++++--- res/values-hi/strings.xml | 19 ++++++++++++++++--- res/values-hr/strings.xml | 12 +++++++++--- res/values-hu/strings.xml | 12 +++++++++--- res/values-hy/strings.xml | 19 ++++++++++++++++--- res/values-in/strings.xml | 12 +++++++++--- res/values-is/strings.xml | 12 +++++++++--- res/values-it/strings.xml | 12 +++++++++--- res/values-iw/strings.xml | 12 +++++++++--- res/values-ja/strings.xml | 12 +++++++++--- res/values-ka/strings.xml | 19 ++++++++++++++++--- res/values-kk/strings.xml | 19 ++++++++++++++++--- res/values-km/strings.xml | 19 ++++++++++++++++--- res/values-kn/strings.xml | 19 ++++++++++++++++--- res/values-ko/strings.xml | 19 ++++++++++++++++--- res/values-ky/strings.xml | 19 ++++++++++++++++--- res/values-lo/strings.xml | 12 +++++++++--- res/values-lt/strings.xml | 12 +++++++++--- res/values-lv/strings.xml | 12 +++++++++--- res/values-mk/strings.xml | 12 +++++++++--- res/values-ml/strings.xml | 19 ++++++++++++++++--- res/values-mn/strings.xml | 12 +++++++++--- res/values-mr/strings.xml | 19 ++++++++++++++++--- res/values-ms/strings.xml | 19 ++++++++++++++++--- res/values-my/strings.xml | 12 +++++++++--- res/values-nb/strings.xml | 12 +++++++++--- res/values-ne/strings.xml | 12 +++++++++--- res/values-nl/strings.xml | 12 +++++++++--- res/values-or/strings.xml | 19 ++++++++++++++++--- res/values-pa/strings.xml | 19 ++++++++++++++++--- res/values-pl/strings.xml | 12 +++++++++--- res/values-pt-rBR/strings.xml | 12 +++++++++--- res/values-pt-rPT/strings.xml | 12 +++++++++--- res/values-pt/strings.xml | 12 +++++++++--- res/values-ro/strings.xml | 12 +++++++++--- res/values-ru/strings.xml | 19 ++++++++++++++++--- res/values-si/strings.xml | 12 +++++++++--- res/values-sk/strings.xml | 12 +++++++++--- res/values-sl/strings.xml | 12 +++++++++--- res/values-sq/strings.xml | 12 +++++++++--- res/values-sr/strings.xml | 12 +++++++++--- res/values-sv/strings.xml | 12 +++++++++--- res/values-sw/strings.xml | 12 +++++++++--- res/values-ta/strings.xml | 19 ++++++++++++++++--- res/values-te/strings.xml | 19 ++++++++++++++++--- res/values-th/strings.xml | 19 ++++++++++++++++--- res/values-tl/strings.xml | 12 +++++++++--- res/values-tr/strings.xml | 12 +++++++++--- res/values-uk/strings.xml | 19 ++++++++++++++++--- res/values-ur/strings.xml | 12 +++++++++--- res/values-uz/strings.xml | 12 +++++++++--- res/values-vi/strings.xml | 19 ++++++++++++++++--- res/values-zh-rCN/strings.xml | 19 ++++++++++++++++--- res/values-zh-rHK/strings.xml | 19 ++++++++++++++++--- res/values-zh-rTW/strings.xml | 19 ++++++++++++++++--- res/values-zu/strings.xml | 12 +++++++++--- 85 files changed, 934 insertions(+), 256 deletions(-) diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml index af0a1c66f..8a75764a3 100644 --- a/res/values-af/strings.xml +++ b/res/values-af/strings.xml @@ -168,6 +168,11 @@ "Maak oop" "Deïnstalleer" "Dwing stop" + "Instellings" + "%s het volle toegang tot jou toestel" + "%s toeganklikheiddienste het volle toegang tot jou toestel" + "%s kan jou skerm, handelinge en invoere bekyk, handelinge uitvoer, en die skerm beheer." + "Hierdie dienste kan jou skerm, handelinge en invoere bekyk, handelinge uitvoer, en die skerm beheer." "Verstekprogramme" "Geen verstekprogramme nie" "Verstek vir werk" @@ -176,6 +181,7 @@ "Spesiale programtoegang" "Geen spesiale programtoegang nie" "Geen programme nie" + "Bystandprogram" "Blaaierprogram" "Foonprogram" "SMS-program" @@ -184,13 +190,13 @@ "Musiekprogram" "Galeryprogram" "Motormodus-foonprogram" - - + "Oproepherleidingprogram" "Oproepsiftingsprogram" "Oproepmetgeselprogram" - "Bystandprogram" "Motorprojeksie-program" + "Steun nie werkprofiel nie" "Let wel: As jy jou toestel herbegin en \'n skermslot is gestel, kan hierdie program nie begin totdat jy jou toestel ontsluit nie." + "Die assistent sal inligting oor programme wat tans op jou stelsel gebruik word, kan lees, insluitend inligting wat op jou skerm sigbaar is of toeganklik is binne die programme." "Deel ontfoutingsdata" "Deel gedetailleerde ontfoutingsdata?" "%1$s wil graag ontfoutingsinligting oplaai." diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml index c931b3433..1beffa73a 100644 --- a/res/values-am/strings.xml +++ b/res/values-am/strings.xml @@ -168,6 +168,11 @@ "ክፈት" "አራግፍ" "በኃይል አቁም" + "ቅንብሮች" + "%s ወደ የእርስዎ መሣሪያ ሙሉ መዳረሻ አለው" + "%s ተደራሽነት አገልግሎቶች ወደ የእርስዎ መሣሪያ ሙሉ መዳረሻ አላቸው።" + "%s የእርስዎን ማያ ገጽ፣ እርምጃዎች እና ግቤቶች መመልከት፣ እርምጃዎችን መውሰድ እና ማሳያን መቆጣጠር ይችላል።" + "እነዚህ አገልግሎቶች የእርስዎን ማያ ገጽ፣ እርምጃዎች እና ግቤቶች መመልከት፣ እርምጃዎችን መውሰድ እና ማሳያን መቆጣጠር ይችላሉ።" "ነባሪ መተግበሪያዎች" "ምንም ነባሪ መተግበሪያዎች የሉም" "ለሥራ ነባሪ" @@ -176,6 +181,7 @@ "ልዩ የመተግበሪያ መዳረሻ" "ምንም ልዩ መተግበሪያ መዳረሻ" "መተግበሪያዎች የሉም" + "የእገዛ መተግበሪያ" "የአሳሽ መተግበሪያ" "የስልክ መተግበሪያ" "የኤስኤምኤስ መተግበሪያ" @@ -184,13 +190,13 @@ "የሙዚቃ መተግበሪያ" "የማዕከለ ሥዕላት መተግበሪያ" "የመኪና ሁነታ የስልክ መተግበሪያ" - - + "የጥሪ ማዞሪያ መተግበሪያ" "የጥሪ ማጣሪያ መተግበሪያ" "የጥሪ አጋር መተግበሪያ" - "የእገዛ መተግበሪያ" "የመኪና መጠበቂያ መተግበሪያ" + "የሥራ መገለጫን አይደግፍም" "ማስታወሻ፦ የእርስዎን መሣሪያ ዳግም ካስጀምሩ እና ማያ ገጽ መቆለፊያው እንዲቀናበር ካደረጉ፣ ይህ መተግበሪያ የእርስዎን መሣሪያ ዳግም እስከሚከፍቱ ድረስ መጀመር አይችልም።" + "ረዳቱ በእርስዎ ስርዓት ላይ በአገልግሎት ላይ ስለሚውሉ መተግበሪያዎች መረጃን ማንበብ ይችላል፣ ይህም በእርስዎ ማያ ገጽ ላይ የሚታይ ወይም በመተግበሪያዎች ውስጥ የሚደረስበት መረጃን ይጨምራል።" "ሳንካ ማረሚያ ውሂብን አጋራ" "ዝርዝር የሳንካ ማረሚያ መረጃ ይጋራ?" "%1$s የሳንካ ማረሚያ መረጃን መስቀል ይፈልጋል።" diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml index 4ec22ab03..106c9bcae 100644 --- a/res/values-ar/strings.xml +++ b/res/values-ar/strings.xml @@ -188,6 +188,11 @@ "فتح" "إلغاء التثبيت" "فرض الإيقاف" + "الإعدادات" + "تحظى خدمة %s بوصول كامل إلى جهازك." + "خدمات إمكانية الوصول التي تحظى بوصول كامل إلى جهازك: %s خدمة" + "يمكن لخدمة %s عرض شاشتك وإجراءاتك ومدخلاتك وتنفيذ الإجراءات والتحكم في العرض." + "يمكن لهذه الخدمات عرض شاشتك وإجراءاتك ومدخلاتك وتنفيذ الإجراءات والتحكم في العرض." "التطبيقات التلقائية" "ليست هناك تطبيقات تلقائية." "التطبيقات التلقائية للعمل" @@ -196,6 +201,7 @@ "أذونات خاصة للتطبيقات" "لا إذن وصول خاص إلى التطبيق." "ليست هناك تطبيقات." + "تطبيق المساعد" "تطبيق المتصفّح" "تطبيق الهاتف" "‏تطبيق SMS" @@ -204,13 +210,13 @@ "تطبيق الموسيقى" "تطبيق المعرض" "تطبيق الهاتف في وضع السيارة" - - + "تطبيق إعادة توجيه المكالمات" "تطبيق فحص المكالمات" "تطبيق مصاحب للمكالمات" - "تطبيق المساعد" "‏تطبيق Car Projection" + "لا يتوافق التطبيق مع الملف الشخصي للعمل." "ملاحظة: في حال إعادة تشغيل جهازك وضبط قفل شاشة، لا يمكن بدء هذا التطبيق إلى أن تفتح جهازك." + "سيتمكن المساعد من قراءة المعلومات عن التطبيقات قيد الاستخدام على نظامك، بما في ذلك المعلومات المرئية على شاشتك أو التي يمكن الوصول إليها داخل التطبيقات." "مشاركة بيانات تصحيح الأخطاء" "هل تريد مشاركة بيانات تصحيح الأخطاء التفصيلية؟" "يريد تطبيق %1$s تحميل معلومات تصحيح الأخطاء." diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml index d48866e43..a9cc502e9 100644 --- a/res/values-as/strings.xml +++ b/res/values-as/strings.xml @@ -168,6 +168,16 @@ "খোলক" "আনইনষ্টল কৰক" "বলেৰে বন্ধ কৰক" + + + + + + + + + + "ডিফ’ল্ট এপ্" "কোনো ডিফ’ল্ট এপ্ নাই" "কৰ্মস্থানৰ বাবে ডিফ’ল্ট" @@ -176,6 +186,7 @@ "বিশেষ এপ্ এক্সেছ" "কোনো বিশেষ এপ্ এক্সেছ নাই" "কোনো এপ্‌ নাই" + "সহায়ক এপ্" "ব্ৰাউজাৰ এপ্" "ফ\'ন এপ্" "এছএমএছ এপ্" @@ -184,13 +195,15 @@ "Music এপ্‌" "Gallery এপ্" "গাড়ী ম’ড ফ’ন এপ্" - - + "কল ৰিডাইৰেক্ট কৰা এপ্" "কল স্ক্ৰীণ কৰা এপ্" "কল সহযোগী এপ্" - "সহায়ক এপ্" "গাড়ীৰ প্ৰজেকশ্বন এপ্‌" + + "টোকা: যদি আপুনি আপোনাৰ ডিভাইচটো ৰিষ্টাৰ্ট কৰে আৰু আপোনাৰ এটা স্ক্ৰীণ লক ছেট কৰি থোৱা আছে, তেন্তে এই এপটো আপুনি ডিভাইচটো আনলক নকৰালৈকে আৰম্ভ নহ’ব।" + + "ডিবাগ ডেটা শ্বেয়াৰ কৰক" "ডিবাগৰ সবিশেষ ডেটা শ্বেয়াৰ কৰিবনে?" "%1$sএ ডিবাগ তথ্য আপল’ড কৰিব বিচাৰিছে।" diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml index 3f24d8559..85d9a9a9b 100644 --- a/res/values-az/strings.xml +++ b/res/values-az/strings.xml @@ -168,6 +168,11 @@ "Açın" "Sistemdən silin" "Məcburi dayandırın" + "Ayarlar" + "%s xidmətinin cihazınıza tam girişi var" + "%s əlçatımlılıq xidmətinin cihazınıza tam giriş icazəsi var" + "%s ekran, əməliyyat və daxiletməyə baxa, əməliyyatlar icra edə və displeyə nəzarət edə bilər." + "Bu xidmətlər ekran, əməliyyat və daxiletməyə baxa, əməliyyatlar icra edə və displeyə nəzarət edə bilər." "Defolt tətbiqlər" "Defolt tətbiq yoxdur" "İş üçün defolt" @@ -176,6 +181,7 @@ "Xüsusi tətbiq girişi" "Xüsusi tətbiq girişi yoxdur" "Tətbiq yoxdur" + "Köməkçi tətbiq" "Brauzer tətbiqi" "Telefon tətbiqi" "SMS tətbiqi" @@ -184,13 +190,13 @@ "Musiqi tətbiqi" "Qalereya tətbiqi" "Avtomobil rejimi olan telefon" - - + "Zəng yönləndirmə tətbiqi" "Ekran zəngi tətbiqi" "Zəng kompanyon tətbiqi" - "Köməkçi tətbiq" "Car Projection tətbiqi" + "İş profilini dəstəkləmir" "Qeyd: Cihazı yenidən başlatmısınızsa və cihazda ekran kilidi varsa, kilidi açmamış tətbiq başlaya bilməz." + "Assistent sistemdə istifadə edilən tətbiqlər haqqında məlumatı oxuya biləcək, bura ekranınızda görünən və ya tətbiqlər daxilində əlçatan olan məlumatlar da daxildir." "Sazlama Datasını Paylaşın" "Ətraflı sazlama datası paylaşılsın?" "%1$s sazlama məlumatını yükləmək istəyir." diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml index d82912ded..959110945 100644 --- a/res/values-b+sr+Latn/strings.xml +++ b/res/values-b+sr+Latn/strings.xml @@ -173,6 +173,11 @@ "Otvori" "Deinstaliraj" "Prinudno zaustavi" + "Podešavanja" + "%s ima potpun pristup uređaju" + "Usluge pristupačnosti (%s) imaju potpun pristup uređaju" + "%s može da pregleda sadržaj ekrana, radnje i unose, obavlja radnje i upravlja ekranom." + "Ove usluge mogu da pregledaju sadržaj ekrana, radnje i unose, obavljaju radnje i upravljaju ekranom." "Podrazumevane aplikacije" "Nema podrazumevane aplikacije." "Podrazumevana za posao" @@ -181,6 +186,7 @@ "Pristup za spec. aplikaciju" "Nema pristupa za spec. apl." "Nema aplikacija" + "Aplikacija za pomoć" "Aplikacija pregledača" "Aplikacija Telefon" "Aplikacija za SMS" @@ -189,13 +195,13 @@ "Aplikacija Muzika" "Aplikacija Galerija" "Aplikacija za telefon sa režimom rada u automobilu" - - + "Aplikacija preusmerava pozive" "Aplik. za uprav. dolaz. poziv." "Pozivanje prateće aplikacije" - "Aplikacija za pomoć" "Aplik. Projekcija u automobilu" + "Ne podržava profil za Work" "Napomena: Ako restartujete uređaj i podesili ste zaključavanje ekrana, ova aplikacija ne može da se pokrene dok ne otključate uređaj." + "Pomoćnik će moći da čita informacije o aplikacijama koje se koriste u sistemu, uključujući informacije vidljive na ekranu ili kojima može da se pristupa u okviru aplikacija." "Deljenje podataka o otklanjanju grešaka" "Delite detaljne podatke za otklanjanje grešaka?" "%1$s želi da otpremi informacije za otklanjanje grešaka." diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml index 15e4ab51b..b8b8a20eb 100644 --- a/res/values-be/strings.xml +++ b/res/values-be/strings.xml @@ -178,6 +178,11 @@ "Адкрыць" "Выдаліць" "Прымусова спыніць" + "Налады" + "%s мае поўны доступ да даных вашай прылады" + "Спецыяльныя магчымасці (%s шт.) маюць поўны доступ да даных вашай прылады" + "%s можа праглядаць ваш экран, дзеянні і ўводы, самастойна выконваць дзеянні і кіраваць дысплэем." + "Гэтыя сэрвісы могуць праглядаць ваш экран, дзеянні і ўводы, самастойна выконваць дзеянні і кіраваць дысплэем." "Стандартныя праграмы" "Няма стандартных праграм" "Стандартныя для працы" @@ -186,6 +191,7 @@ "Спецыяльны доступ да праграм" "Няма доступу да праграм" "Няма праграм" + "Праграма-памочнік" "Браўзер" "Праграма \"Тэлефон\"" "Праграма для SMS" @@ -194,13 +200,13 @@ "Праграма \"Музыка\"" "Праграма \"Галерэя\"" "Праграма рэжыму \"У аўтамабілі\"" - - + "Праграма перанакіравання выклікаў" "Праграма фільтравання выклікаў" "Спадарожная праграма выклікаў" - "Праграма-памочнік" "Праграма трансляцыі на экран" + "Працоўны профіль не падтрымліваецца" "Заўвага. Калі перазапусціць прыладу з наладжанай блакіроўкай экрана, праграма не запусціцца, пакуль вы не разблакіруеце прыладу." + "Памочнік атрымае доступ да інфармацыі пра праграмы, якія выкарыстоўваюцца ў вашай сістэме, у тым ліку да інфармацыі, бачнай на вашым экране ці даступнай у праграмах." "Абагульванне даных адладкі" "Абагуліць падрабязнасці адладкі?" "Праграма \"%1$s\" спрабуе запампаваць звесткі пра адладку." diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml index ea973e385..10770abdb 100644 --- a/res/values-bg/strings.xml +++ b/res/values-bg/strings.xml @@ -168,6 +168,11 @@ "Отваряне" "Деинсталиране" "Принудително спиране" + "Настройки" + "%s има пълен достъп до устройството ви" + "%s услуги за достъпност имат пълен достъп до устройството ви" + "%s може да вижда екрана, действията ви и данните, които въвеждате, както и да извършва действия и да контролира дисплея." + "Тези услуги могат да виждат екрана, действията ви и данните, които въвеждате, както и да извършват действия и да контролират дисплея." "Приложения по подразбиране" "Няма стандартни приложия" "По подразбиране за работа" @@ -176,6 +181,7 @@ "Специален достъп за прилож." "Няма спец. достъп за прилож." "Няма приложения" + "Помощно приложение" "Приложение за браузър" "Приложение за телефон" "Приложение за SMS" @@ -184,13 +190,13 @@ "Приложение за музика" "Приложение за галерия" "Прил. за телефон в моторежим" - - + "Прил. за пренас. на обаждания" "Прил. за отсяване на обажд." "Придружаващо прил. за обажд." - "Помощно приложение" "Прожектиране в автомобила" + "Не се поддържат служебни потребителски профили" "Забележка: Ако рестартирате устройството си и сте задали опция за заключване на екрана, това приложение не може да стартира, докато не отключите устройството си." + "Асистентът ще може да чете информацията за използваните в системата приложения, включително данните, видими на екрана или достъпни в тях." "Споделяне на данните за отстраняване на грешки" "Споделяне на подробни данни за отстран. на грешки?" "%1$s иска да качи информация за отстраняване на грешки." diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml index 1bc1c7262..85168da0b 100644 --- a/res/values-bn/strings.xml +++ b/res/values-bn/strings.xml @@ -168,6 +168,16 @@ "খুলুন" "আন-ইনস্টল করুন" "জোর করে বন্ধ করুন" + + + + + + + + + + "ডিফল্ট অ্যাপ" "কোনও ডিফল্ট অ্যাপ নেই" "অফিসের জন্য ডিফল্ট" @@ -176,6 +186,7 @@ "অ্যাপের বিশেষ অ্যাক্সেস" "অ্যাপের বিশেষ অ্যাক্সেস নেই" "কোনও অ্যাপ নেই" + "সহায়তা অ্যাপ" "ব্রাউজার অ্যাপ" "ফোন অ্যাপ" "এসএমএস অ্যাপ" @@ -184,13 +195,15 @@ "মিউজিক অ্যাপ" "গ্যালারি অ্যাপ" "গাড়ির মোডে ফোন অ্যাপ" - - + "কল রিডাইরেক্ট করার অ্যাপ" "কল স্ক্রিনিং অ্যাপ" "কল কম্প্যানিয়ন অ্যাপ" - "সহায়তা অ্যাপ" "গাড়ির প্রোজেকশন অ্যাপ" + + "দ্রষ্টব্য: আপনি যদি নিজের ডিভাইস রিস্টার্ট করেন এবং স্ক্রিন লক সেট করা থাকে, তাহলে আপনার ডিভাইস আনলক না করা পর্যন্ত আপনি এই অ্যাপটি চালু করতে পারবেন না।" + + "ডিবাগিং ডেটা শেয়ার করুন" "ডিবাগিংয়ের বিস্তারিত ডেটা শেয়ার করতে চান?" "%1$s ডিবাগিংয়ের তথ্য আপলোড করতে চায়।" diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml index 59d49be62..cebacca7f 100644 --- a/res/values-bs/strings.xml +++ b/res/values-bs/strings.xml @@ -173,6 +173,11 @@ "Otvori" "Deinstaliraj" "Prisilno zaustavi" + "Postavke" + "Usluga %s ima potpuni pristup vašem uređaju" + "Sljedeći broj usluga za pristupačnost ima potpuni pristup vašem uređaju: %s" + "Usluga %s može pregledati vaš ekran, radnje i unose, a može i izvršavati radnje i kontrolirati ekran." + "Ove usluge mogu pregledati vaš ekran, radnje i unose, a mogu i izvršavati radnje i kontrolirati ekran." "Zadane aplikacije" "Nema zadanih aplikacija" "Uobičajeno za rad" @@ -181,6 +186,7 @@ "Poseban pristup aplikacijama" "Nema pristupa posebnim apl." "Nema aplikacija" + "Aplikacija za pomoć" "Aplikacija preglednika" "Aplikacija Telefon" "Aplikacija za SMS" @@ -189,13 +195,13 @@ "Aplikacija za muziku" "Aplikacija galerije" "Apl. za način rada u automob." - - + "Aplikacija za preusmjeravanje poziva" "Aplik. za filtriranje poziva" "Prateća aplikacija za pozive" - "Aplikacija za pomoć" "Apl. za projekciju u automobilu" + "Radni profil nije podržan" "Napomena: Ako ponovo pokrenete uređaj, a postavili ste zaključavanje ekrana, ova aplikacija se neće moći pokrenuti dok ne otključate uređaj." + "Asistent će imati mogućnost čitanja informacija o aplikacijama koje se koriste na vašem sistemu, uključujući informacije vidljive na ekranu ili dostupne unutar aplikacija." "Dijeljenje podataka o otklanjanju grešaka" "Dijeliti detaljne podatke o otklanjanju grešaka?" "Aplikacija %1$s želi otpremiti informacije o otklanjanju grešaka." diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml index 64952e236..5adaa3e53 100644 --- a/res/values-ca/strings.xml +++ b/res/values-ca/strings.xml @@ -168,6 +168,11 @@ "Obre" "Desinstal·la" "Força l\'aturada" + "Configuració" + "%s té accés complet al dispositiu" + "%s serveis d\'accessibilitat tenen accés complet al dispositiu" + "%s pot veure la pantalla, les accions i el text que s\'introdueix, dur a terme accions i controlar la pantalla." + "Aquests serveis poden veure la pantalla, les accions i el text que s\'introdueix, dur a terme accions i controlar la pantalla." "Aplicacions predeterminades" "Cap aplicació predeterminada" "Predeterminada per a la feina" @@ -176,6 +181,7 @@ "Accés especial d\'aplicacions" "Sense accés especial d\'apps" "No hi ha cap aplicació" + "Aplicació d\'assistència" "Aplicació de navegador" "Aplicació Telèfon" "Aplicació d\'SMS" @@ -184,13 +190,13 @@ "Aplicació Música" "Aplicació Galeria" "Aplicació mode de cotxe" - - + "App per redirigir trucades" "Aplicació per filtrar trucades" "Aplicació complementària de trucades" - "Aplicació d\'assistència" "Aplicació projecció del cotxe" + "No admet els perfils professionals" "Nota: si reinicies el dispositiu i has definit un bloqueig de pantalla, l\'aplicació no s\'iniciarà fins que no desbloquegis el dispositiu." + "L\'assistent podrà llegir informació sobre les aplicacions que s\'utilitzen al teu sistema; també podrà accedir a la informació que es veu en pantalla o a què accedeixes des de les aplicacions." "Comparteix les dades de depuració" "Vols compartir els detalls de la depuració?" "%1$s vol penjar informació de depuració." diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml index 5f1e7ac0b..8664a2b60 100644 --- a/res/values-cs/strings.xml +++ b/res/values-cs/strings.xml @@ -178,6 +178,11 @@ "Otevřít" "Odinstalovat" "Vynutit ukončení" + "Nastavení" + "Služba %s má plný přístup k vašemu zařízení" + "Služby přístupnosti, které mají plný přístup k vašemu zařízení: %s" + "Služba %s může zobrazit vaši obrazovku, akce a vstup, provádět akce a ovládat obrazovku." + "Tyto služby mohou zobrazit vaši obrazovku, akce a vstup, provádět akce a ovládat obrazovku." "Výchozí aplikace" "Žádné výchozí aplikace" "Výchozí pracovní" @@ -186,6 +191,7 @@ "Přístup ke spec. aplikacím" "Žádný přístup ke spec. aplik." "Žádné aplikace" + "Asistenční aplikace" "Prohlížeč" "Aplikace Telefon" "Aplikace pro SMS" @@ -194,13 +200,13 @@ "Aplikace Hudba" "Aplikace Galerie" "Telefonování v autě" - - + "Aplikace k přesměrování hovorů" "Ohlašování jména volajícího" "Doprovod. aplikace na volání" - "Asistenční aplikace" "Aplikace na promítání do auta" + "Nepodporuje pracovní profil" "Poznámka: Pokud restartujete zařízení a máte nastavený zámek obrazovky, tato aplikace se nespustí, dokud zařízení neodemknete." + "Asistent bude moci číst informace o aplikacích používaných v systému, včetně údajů viditelných na obrazovce a přístupných v rámci aplikací." "Sdílet data ladění" "Sdílet podrobná data pro ladění?" "Aplikace %1$s chce nahrát informace pro ladění." diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml index b272e6b46..d09556acb 100644 --- a/res/values-da/strings.xml +++ b/res/values-da/strings.xml @@ -168,6 +168,11 @@ "Åbn" "Afinstaller" "Tving til at standse" + "Indstillinger" + "%s har fuld adgang til din enhed" + "%s hjælpefunktioner har fuld adgang til din enhed" + "%s kan se din skærm, dine handlinger og dine input samt udføre handlinger og styre skærmen" + "Disse hjælpefunktioner kan se din skærm, dine handlinger og dine input samt udføre handlinger og styre skærmen." "Standardapps" "Ingen standardapps." "Standard til arbejde" @@ -176,6 +181,7 @@ "Særlig appadgang" "Ingen særlig appadgang" "Ingen apps" + "Assistanceapp" "Browserapp" "Appen Opkald" "Sms-app" @@ -184,13 +190,13 @@ "Musikapp" "Galleriapp" "Telefonapp til biltilstand" - - + "App til opkaldsviderestilling" "App til opkaldsvalg" "Medfølgende opkaldsapp" - "Assistanceapp" "Appen Bilprojicering" + "Arbejdsprofilen understøttes ikke" "Bemærk! Hvis du genstarter din enhed og har indstillet en skærmlås, kan denne app ikke starte, før du låser enheden op." + "Assistenten kan læse oplysninger om, hvilke apps der bruges i dit system, bl.a. oplysninger, der er synlige på din skærm eller tilgængelige i dine apps." "Del fejlretningsdata" "Vil du dele detaljerede fejlretningsdata?" "%1$s vil gerne uploade fejretningsoplysninger." diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index 47c1f4b2c..a945f32cb 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -168,6 +168,11 @@ "Öffnen" "Deinstallieren" "Beenden erzwingen" + "Einstellungen" + "%s hat uneingeschränkten Zugriff auf dein Gerät" + "%s Bedienungshilfen haben uneingeschränkten Zugriff auf dein Gerät" + "%s kann deinen Bildschirm, deine Aktionen und Eingaben sehen, Aktionen ausführen und den Bildschirm steuern." + "Diese Dienste können deinen Bildschirm, deine Aktionen und Eingaben sehen, Aktionen ausführen und den Bildschirm steuern." "Standard-Apps" "Keine Standard-Apps" "Standardeinstellung für Arbeit" @@ -176,6 +181,7 @@ "Spezieller App-Zugriff" "Kein spezieller App-Zugriff" "Keine Apps" + "Assistent-App" "Browser-App" "Telefon-App" "SMS-App" @@ -184,13 +190,13 @@ "Musik App" "Galerie App" "Automodus-Telefon-App" - - + "App zur Anrufweiterleitung" "Call Screening-App" "Companion App für Anrufe" - "Assistent-App" "App \"Übertragung an Auto\"" + "Unterstützt das Arbeitsprofil nicht" "Hinweis: Hinweis: Wenn du dein Gerät neu startest und eine Displaysperre aktiviert ist, wird diese App erst gestartet, wenn du dein Gerät entsperrst." + "Der Assistent kann Informationen zu Apps abrufen, die du auf deinem System verwendest, einschließlich Informationen, die auf deinem Bildschirm angezeigt werden oder die in Apps zugänglich sind." "Daten zur Fehlerbehebung teilen" "Detaillierte Daten zur Fehlerbehebung teilen?" "%1$s möchte Informationen zur Fehlerbehebung hochladen." diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml index cb9f34fef..500f7125f 100644 --- a/res/values-el/strings.xml +++ b/res/values-el/strings.xml @@ -168,6 +168,11 @@ "Άνοιγμα" "Απεγκατάσταση" "Αναγκαστική διακοπή" + "Ρυθμίσεις" + "Η υπηρεσία %s έχει πλήρη πρόσβαση στη συσκευή σας" + "%s υπηρεσίες προσβασιμότητας έχουν πλήρη πρόσβαση στη συσκευή σας" + "Η υπηρεσία %s μπορεί να δει την οθόνη σας, τις ενέργειες και τις καταχωρίσεις, να εκτελέσει ενέργειες και να ελέγξει την οθόνη." + "Αυτές οι υπηρεσίες μπορούν να δουν την οθόνη σας, τις ενέργειες και τις καταχωρίσεις, να εκτελέσουν ενέργειες και να ελέγξουν την οθόνη." "Προεπιλεγμένες εφαρμογές" "Καμία προεπιλεγμένη εφαρμογή" "Προεπιλογή για εργασία" @@ -176,6 +181,7 @@ "Ειδική άδεια εφαρμογής" "Χωρίς ειδική άδεια εφαρμογής" "Καμία εφαρμογή" + "Εφαρμογή υποβοήθειας" "Εφαρμ. προγράμματος περιήγησης" "Εφαρμογή \"Τηλέφωνο\"" "Εφαρμογή SMS" @@ -184,13 +190,13 @@ "Εφαρμογή μουσικής" "Εφαρμογή Gallery" "Εφαρ. \"τηλέφωνο\" σε λειτ. αυτ." - - + "Εφαρμογή ανακατεύθ. κλήσεων" "Εφαρμογή διαλογής κλήσεων" "Συνοδευτική εφαρμογή κλήσης" - "Εφαρμογή υποβοήθειας" "Εφαρμ. προβολής στο αυτοκίνητο" + "Δεν υποστηρίζει προφίλ εργασίας" "Σημείωση: Εάν έχετε ορίσει ένα κλείδωμα οθόνης και επανεκκινήσετε τη συσκευή, η εκκίνηση αυτής της εφαρμογής δεν θα είναι δυνατή έως ότου ξεκλειδώσετε τη συσκευή σας." + "Ο Βοηθός θα μπορεί να διαβάσει πληροφορίες σχετικά με τις εφαρμογές που χρησιμοποιούνται στο σύστημά σας, συμπεριλαμβανομένων πληροφοριών που είναι ορατές στην οθόνη σας ή προσβάσιμες εντός των εφαρμογών." "Κοινοποίηση δεδομένων εντοπισμού σφαλμάτων" "Κοινοποίηση λεπτομερ. δεδομ. εντοπισμού σφαλμάτων;" "Η εφαρμογή %1$s θέλει να ανεβάσει πληροφορίες εντοπισμού σφαλμάτων." diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml index 96852c74a..c1b477040 100644 --- a/res/values-en-rAU/strings.xml +++ b/res/values-en-rAU/strings.xml @@ -168,6 +168,11 @@ "Open" "Uninstall" "Force stop" + "Settings" + "%s has full access to your device" + "%s accessibility services have full access to your device" + "%s can view your screen, actions and inputs, perform actions and control the display." + "These services can view your screen, actions and inputs, perform actions and control the display." "Default apps" "No default apps" "Default for work" @@ -176,6 +181,7 @@ "Special app access" "No special app access" "No apps" + "Assist app" "Browser app" "Phone app" "SMS app" @@ -184,13 +190,13 @@ "Music app" "Gallery app" "Car mode phone app" - - + "Call redirecting app" "Call screening app" "Call companion app" - "Assist app" "Car Projection app" + "Doesn’t support work profile" "Note: If you restart your device and have a screen lock set, this app can’t start until you unlock your device." + "The Assistant will be able to read information about apps that are in use on your system, including information visible on your screen or accessible within the apps." "Share Debugging Data" "Share detailed debugging data?" "%1$s would like to upload debugging information." diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml index 96852c74a..c1b477040 100644 --- a/res/values-en-rCA/strings.xml +++ b/res/values-en-rCA/strings.xml @@ -168,6 +168,11 @@ "Open" "Uninstall" "Force stop" + "Settings" + "%s has full access to your device" + "%s accessibility services have full access to your device" + "%s can view your screen, actions and inputs, perform actions and control the display." + "These services can view your screen, actions and inputs, perform actions and control the display." "Default apps" "No default apps" "Default for work" @@ -176,6 +181,7 @@ "Special app access" "No special app access" "No apps" + "Assist app" "Browser app" "Phone app" "SMS app" @@ -184,13 +190,13 @@ "Music app" "Gallery app" "Car mode phone app" - - + "Call redirecting app" "Call screening app" "Call companion app" - "Assist app" "Car Projection app" + "Doesn’t support work profile" "Note: If you restart your device and have a screen lock set, this app can’t start until you unlock your device." + "The Assistant will be able to read information about apps that are in use on your system, including information visible on your screen or accessible within the apps." "Share Debugging Data" "Share detailed debugging data?" "%1$s would like to upload debugging information." diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml index 96852c74a..c1b477040 100644 --- a/res/values-en-rGB/strings.xml +++ b/res/values-en-rGB/strings.xml @@ -168,6 +168,11 @@ "Open" "Uninstall" "Force stop" + "Settings" + "%s has full access to your device" + "%s accessibility services have full access to your device" + "%s can view your screen, actions and inputs, perform actions and control the display." + "These services can view your screen, actions and inputs, perform actions and control the display." "Default apps" "No default apps" "Default for work" @@ -176,6 +181,7 @@ "Special app access" "No special app access" "No apps" + "Assist app" "Browser app" "Phone app" "SMS app" @@ -184,13 +190,13 @@ "Music app" "Gallery app" "Car mode phone app" - - + "Call redirecting app" "Call screening app" "Call companion app" - "Assist app" "Car Projection app" + "Doesn’t support work profile" "Note: If you restart your device and have a screen lock set, this app can’t start until you unlock your device." + "The Assistant will be able to read information about apps that are in use on your system, including information visible on your screen or accessible within the apps." "Share Debugging Data" "Share detailed debugging data?" "%1$s would like to upload debugging information." diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml index 96852c74a..c1b477040 100644 --- a/res/values-en-rIN/strings.xml +++ b/res/values-en-rIN/strings.xml @@ -168,6 +168,11 @@ "Open" "Uninstall" "Force stop" + "Settings" + "%s has full access to your device" + "%s accessibility services have full access to your device" + "%s can view your screen, actions and inputs, perform actions and control the display." + "These services can view your screen, actions and inputs, perform actions and control the display." "Default apps" "No default apps" "Default for work" @@ -176,6 +181,7 @@ "Special app access" "No special app access" "No apps" + "Assist app" "Browser app" "Phone app" "SMS app" @@ -184,13 +190,13 @@ "Music app" "Gallery app" "Car mode phone app" - - + "Call redirecting app" "Call screening app" "Call companion app" - "Assist app" "Car Projection app" + "Doesn’t support work profile" "Note: If you restart your device and have a screen lock set, this app can’t start until you unlock your device." + "The Assistant will be able to read information about apps that are in use on your system, including information visible on your screen or accessible within the apps." "Share Debugging Data" "Share detailed debugging data?" "%1$s would like to upload debugging information." diff --git a/res/values-en-rXC/strings.xml b/res/values-en-rXC/strings.xml index 52973f857..f75d663bd 100644 --- a/res/values-en-rXC/strings.xml +++ b/res/values-en-rXC/strings.xml @@ -168,6 +168,11 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‏‎‏‎‎‏‏‎‏‎‎‏‏‎‎‏‎‎‏‎‏‏‎‏‏‎‎‏‎‎‏‏‎‎‎‏‏‏‏‏‎‏‎‏‏‎‏‏‏‎‏‏‎Open‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‎‏‎‏‎‏‎‏‏‏‎‏‎‏‎‏‎‏‎‎‎‏‎‎‎‏‎‎‎‏‎‎‎‏‎‏‎‎‎‎‏‎‏‏‏‎‏‏‏‏‏‎‎Uninstall‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‎‎‎‎‎‏‏‏‎‎‏‏‎‏‎‎‏‎‏‏‎‏‎‎‏‎‎‎‏‏‎‏‎‏‏‎‎‎‎‏‏‏‎‏‎‏‏‎‏‎‎‏‎‎‏‎‎Force stop‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‎‎‎‎‎‏‏‎‎‏‏‏‎‏‏‏‏‎‎‏‏‏‏‏‎‎‏‎‎‏‎‎‏‏‎‏‏‏‏‏‎‏‏‎‏‏‎‎‏‎‏‎‏‎‏‏‎Settings‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‎‏‏‎‎‏‎‎‎‎‏‎‎‏‏‎‏‎‎‎‏‏‏‏‏‎‏‎‎‏‏‏‎‎‎‎‏‎‏‏‏‏‎‎‎‏‎‎‎‏‏‏‏‏‎‏‎‎‏‎‎‏‏‎%s‎‏‎‎‏‏‏‎ has full access to your device‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‏‏‎‎‎‎‏‎‏‏‎‏‎‏‏‏‏‏‎‎‎‏‎‏‎‏‎‏‎‎‏‎‏‎‏‏‎‎‎‎‏‎‏‎‎‎‏‏‏‏‎‎‏‎‎‎‏‎‎‏‎‎‏‏‎%s‎‏‎‎‏‏‏‎ accessibility services have full access to your device‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‏‏‎‏‏‎‎‏‎‎‏‎‏‎‏‏‎‏‎‎‏‎‎‏‎‎‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‎‎‎‏‏‎‎‏‏‏‎‏‎‎‏‎‎‏‏‎%s‎‏‎‎‏‏‏‎ can view your screen, actions, and inputs, perform actions, and control the display.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‎‏‎‏‏‎‎‏‎‏‏‏‎‎‎‏‎‎‏‎‎‏‎‎‏‎‏‏‏‏‏‎‎‎‏‏‎‏‏‏‏‎‏‎‏‎‏‏‎‎‎‎‏‎‎‏‎These services can view your screen, actions, and inputs, perform actions, and control the display.‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‏‏‏‏‏‎‎‏‏‎‎‏‎‎‏‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‏‏‏‎‏‏‎‏‏‏‏‏‏‎‏‎‎‎‏‎‎‎Default apps‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‏‏‏‎‏‏‏‏‎‎‏‏‏‎‎‎‏‎‏‎‎‏‏‏‎‎‏‎‎‏‎‏‎‎‏‏‎‎‏‏‎‏‏‏‏‏‏‏‏‎‎‎‎No default apps‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‏‏‎‎‏‏‏‏‎‏‏‎‏‏‎‏‏‏‎‏‏‏‎‏‏‎‏‎‎‎‏‏‎‎‎‎‎‎‎‏‏‎‎‏‎‎‎‎‏‏‎‎‎‎Default for work‎‏‎‎‏‎" @@ -176,6 +181,7 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎‎‎‏‏‎‎‏‏‏‎‎‏‎‎‏‏‏‎‎‏‎‎‎‏‎‏‏‎‏‏‎‎‎‏‏‏‏‏‎‎‎‏‎‎‎‏‏‏‏‎‏‏‎‏‎Special app access‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‏‏‎‎‏‏‏‎‏‏‎‏‏‏‏‎‏‏‏‎‏‎‏‎‏‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‎‎‏‎‏‎‎‏‏‏‎‏‎‎‏‏‎No special app access‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‏‎‎‏‏‎‏‏‎‎‎‏‎‏‏‎‏‎‏‏‎‎‎‏‎‏‏‎‎‏‎‎‏‎‏‏‎‎‎‎‎‏‏‎‎‏‏‎‎‏‎‏‎‎‏‎‎No apps‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‎‏‎‏‎‏‏‎‎‏‏‏‏‎‎‎‏‎‏‏‎‏‏‏‏‎‏‏‎‎‎‎‏‎‎‎‎‏‏‏‏‏‏‎‎‎‎‎‏‎‎‎‎‏‎‎‎Assist app‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‏‏‏‎‏‏‏‎‎‎‏‎‏‏‎‏‎‎‏‎‏‎‎‏‎‏‎‏‏‎‎‎‎‏‎‎‏‎‏‎‎‏‎‎‏‏‏‎‏‎‏‎‎‎‏‎Browser app‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‎‏‏‎‏‏‏‏‎‎‎‎‎‎‎‏‏‏‎‏‏‎‏‏‏‎‎‏‎‎‏‎‎‏‏‎‎‏‏‎‏‎‏‏‎‎‏‏‎‎‎‏‏‏‎‏‎Phone app‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‏‏‏‏‎‎‎‎‏‏‏‏‏‎‎‎‏‎‎‏‎‎‏‏‎‏‎‏‏‎‏‏‏‎‏‏‏‏‎‎‏‏‏‎‎‏‎‎SMS app‎‏‎‎‏‎" @@ -184,13 +190,13 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‏‎‎‎‎‏‏‏‏‎‎‎‎‏‏‏‏‏‎‎‎‏‏‎‏‎‏‎‎‎‏‎‏‏‎‏‏‎‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎Music app‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‎‎‏‏‏‎‎‏‎‎‎‏‎‏‎‏‎‎‎‏‎‏‎‎‎‎‎‎‎‎‏‏‏‎‏‏‎‏‏‏‎‎‎‏‎‎‎‎‎‎‏‎‎‏‎Gallery app‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎‏‎‏‏‏‏‎‏‎‎‏‎‎‏‎‎‏‏‏‏‎‎‎‎‏‎‎‎‏‎‏‎‏‏‎‎‏‎‎‎‏‏‏‎‏‎‎‏‎‎‏‏‏‎Car mode phone app‎‏‎‎‏‎" - - + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‏‎‏‎‏‏‏‏‎‏‎‏‎‎‏‎‏‎‏‏‏‎‎‏‏‏‎‎‏‎‏‏‏‏‎‎‏‏‏‎‏‎‎‎‏‏‎‏‏‎‎‏‎Call redirecting app‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‏‏‎‏‏‎‏‎‎‏‏‏‎‏‎‏‏‏‎‏‎‏‎‏‏‏‏‏‏‎‏‎‎‎‎‎‏‏‎‏‏‎‎‏‏‎‏‎‎‏‎‎‏‎‎‏‎‎Call screening app‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‎‎‎‏‏‎‏‎‎‎‎‏‎‎‏‏‎‎‏‏‎‏‏‏‎‎‏‏‎‏‎‎‎‏‎‎‏‎‎‎‏‎‎‏‏‏‎‎‏‏‎‎‏‏‎Call companion app‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‎‏‎‏‎‏‏‎‎‏‏‏‏‎‎‎‏‎‏‏‎‏‏‏‏‎‏‏‎‎‎‎‏‎‎‎‎‏‏‏‏‏‏‎‎‎‎‎‏‎‎‎‎‏‎‎‎Assist app‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‏‎‏‎‎‎‏‏‎‎‏‏‎‎‎‎‏‏‏‎‏‎‏‎‎‏‎‏‏‏‎‏‏‎‎‎‎‎‏‎‎‏‎‎‏‏‏‏‎‏‏‎‏‏‎‏‎Car Projection app‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‏‎‏‏‏‏‎‎‏‎‏‏‎‎‏‏‎‏‎‎‏‏‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‎‎‎‏‎Doesn’t support work profile‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‏‏‏‏‎‏‎‏‎‎‏‏‎‏‏‏‎‏‏‎‎‎‎‎‎‏‎‎‏‎‏‏‏‏‏‏‎‏‎‏‏‎‏‏‎‏‎‏‎‏‎‎‏‏‎‎‎Note: If you restart your device and have a screen lock set, this app can’t start until you unlock your device.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‎‏‏‏‎‏‏‎‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‎‎‎‏‏‏‏‎‏‏‏‏‎‏‏‏‎‎‏‏‎‎‎‏‏‎‏‏‎‎‎‎The assistant will be able to read information about apps in use on your system, including information visible on your screen or accessible within the apps.‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‎‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‎‎‎‎‎‏‏‎‎‏‎‎‎‏‏‏‎‎‏‎‏‎‏‏‎‏‎‏‏‎‎Share Debugging Data‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‏‎‎‏‏‎‎‎‎‎‎‏‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‎‎‎‎‏‎‏‏‏‎‏‎‏‏‎‎Share detailed debugging data?‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‎‏‎‏‎‏‎‏‏‎‏‎‎‎‏‎‎‏‏‏‎‏‏‎‎‎‏‎‎‎‏‏‏‏‏‎‏‎‏‏‏‏‏‏‎‎‎‏‎‏‎‎‎‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ would like to upload debugging information.‎‏‎‎‏‎" diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml index 5cd059ded..c51cc3e80 100644 --- a/res/values-es-rUS/strings.xml +++ b/res/values-es-rUS/strings.xml @@ -168,6 +168,11 @@ "Abrir" "Desinstalar" "Forzar detención" + "Configuración" + "%s tiene acceso completo a tu dispositivo" + "%s servicios de accesibilidad tienen acceso completo a tu dispositivo" + "%s puede ver tu pantalla, lo que haces y lo que introduces, así como realizar acciones y controlar la pantalla." + "Estos servicios pueden ver tu pantalla, lo que haces y lo que introduces, así como realizar acciones y controlar la pantalla." "Apps predeterminadas" "Sin apps predeterminadas" "Predeterminadas de trabajo" @@ -176,6 +181,7 @@ "Acceso especial a apps" "No hay acceso especial a apps" "No hay apps" + "Aplicación de asistencia" "App de navegador" "App de teléfono" "app de SMS" @@ -184,13 +190,13 @@ "App de Música" "App de Galería" "App de teléfono en modo auto" - - + "App para desviar llamadas" "App de filtro de llamadas" "App de llamadas complementaria" - "Aplicación de asistencia" "App de proyección del auto" + "No admite el perfil de trabajo" "Nota: Si reinicias el dispositivo y tienes configurado un bloqueo de pantalla, no podrá iniciarse la app hasta que lo desbloquees." + "El Asistente podrá leer información sobre las apps del sistema en uso, incluidos los datos visibles en la pantalla o a los que se puede acceder mediante apps." "Compartir datos de depuración" "¿Compartir datos detallados de depuración?" "%1$s quiere subir información de depuración." diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index 7fffac15b..242e05b4d 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -168,6 +168,11 @@ "Abrir" "Desinstalar" "Forzar detención" + "Ajustes" + "%s tiene acceso completo a tu dispositivo" + "%s servicios de accesibilidad tienen acceso completo a tu dispositivo" + "%s puede ver tu pantalla, lo que haces y lo que introduces; realizar acciones; y controlar la pantalla." + "Estos servicios pueden ver tu pantalla, lo que haces y lo que introduces; realizar acciones; y controlar la pantalla." "Aplicaciones predeterminadas" "Ninguna app predeterminada" "Predeterminadas para trabajo" @@ -176,6 +181,7 @@ "Acceso especial de apps" "Sin acceso especial de apps" "No hay aplicaciones" + "Aplicación de asistencia" "Aplicación de navegador" "Aplicación de teléfono" "Aplicación de SMS" @@ -184,13 +190,13 @@ "Aplicación de música" "Aplicación de galería" "App de llamadas en modo coche" - - + "App de redirección de llamadas" "App de filtro de llamadas" "App complementaria de llamadas" - "Aplicación de asistencia" "App de proyección del coche" + "No admite perfiles de trabajo" "Nota: Si reinicias el dispositivo y y has definido un bloqueo de pantalla, esta aplicación no se podrá iniciar hasta que desbloquees el dispositivo." + "El asistente podrá consultar información sobre las aplicaciones en uso del sistema, como la que aparezca en pantalla o a la que se pueda acceder a través de las aplicaciones." "Compartir datos de depuración" "¿Quieres compartir datos de depuración detallados?" "%1$s quiere subir información de depuración." diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml index d43ac509b..092a649ae 100644 --- a/res/values-et/strings.xml +++ b/res/values-et/strings.xml @@ -168,6 +168,11 @@ "Ava" "Desinstalli" "Sundpeata" + "Seaded" + "Teenusel %s on täielik juurdepääs teie seadmele" + "%s juurdepääsetavusteenusel on täielik juurdepääs teie seadmele" + "%s saab vaadata teie ekraanikuva, toiminguid ja sisendeid, teha toiminguid ning juhtida ekraani." + "Need teenused saavad vaadata teie ekraanikuva, toiminguid ja sisendeid, teha toiminguid ning juhtida ekraani." "Vaikerakendused" "Vaikerakendusi pole" "Vaikerakendused töö jaoks" @@ -176,6 +181,7 @@ "Rakenduste erijuurdepääs" "Rakenduse erijuurdepääs puudub" "Rakendusi pole" + "Abirakendus" "Brauserirakendus" "Telefonirakendus" "SMS-i rakendus" @@ -184,13 +190,13 @@ "Muusikarakendus" "Galeriirakendus" "Autorežiimi telefonirakendus" - - + "Kõnede ümbersuunamise rakendus" "Kõnede filtreerimise rakendus" "Helistamise kaasrakendus" - "Abirakendus" "Auto projektsiooni rakendus" + "Ei toeta tööprofiili" "Märkus Kui taaskäivitate seadme ja olete määranud ekraaniluku, ei saa see rakendus käivituda enne, kui oma seadme avate." + "Assistent saab teie süsteemis kasutatavate rakenduste kohta teavet (sh teie ekraanil kuvatud või rakendustes juurdepääsetavat teavet) lugeda." "Silumisandmete jagamine" "Kas jagada üksikasjalikke silumisandmeid?" "%1$s soovib üles laadida silumisteavet." diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml index 81c174454..ef93d23d0 100644 --- a/res/values-eu/strings.xml +++ b/res/values-eu/strings.xml @@ -168,6 +168,11 @@ "Ireki" "Desinstalatu" "Behartu gelditzera" + "Ezarpenak" + "%s zerbitzuak gailurako sarbide osoa du" + "%s erabilerraztasun-zerbitzuk dute gailurako sarbide osoa" + "%s zerbitzuak pantaila, egiten dituzun ekintzak eta idazten dituzun gauzak ikusi ahalko ditu, bai eta ekintzak gauzatu eta pantaila kontrolatu ere." + "Zerbitzu horiek pantaila, egiten dituzun ekintzak eta idazten dituzun gauzak ikusi ahalko dituzte, bai eta ekintzak gauzatu eta pantaila kontrolatu ere." "Aplikazio lehenetsiak" "Ez dago aplikazio lehenetsirik" "Lanerako aplikazio lehenetsiak" @@ -176,6 +181,7 @@ "Aplikazio-baimen bereziak" "Ez dago aplikazio-baimen berezirik" "Ez dago aplikaziorik" + "Laguntza-aplikazioa" "Arakatzailea" "Telefonoa" "SMS" @@ -184,13 +190,13 @@ "Musika aplikazioa" "Galeria aplikazioa" "Gidatze modua ezartzeko aplikazioa" - - + "Deiak birbideratzeko aplikazioa" "Deiak iragazteko aplikazioa" "Deien aplikazio osagarria" - "Laguntza-aplikazioa" "Autoan islatzeko aplikazioa" + "Ez ditu onartzen laneko profilak" "Oharra: gailua berrabiarazten baduzu eta pantailaren blokeoa badaukazu ezarrita, ezingo da abiarazi aplikazioa gailua desblokeatzen duzun arte." + "Zure sistemak darabiltzan aplikazioei buruzko informazioa irakurri ahal izango du laguntzaileak; besteak beste, pantailan ikusgai duzun edo aplikazioetatik atzi daitekeen informazioa." "Partekatu arazketa-datuak" "Arazketa-datu xehatuak partekatu nahi dituzu?" "%1$s aplikazioak arazketa-informazioa kargatu nahi du." diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml index 37dec7895..7971579be 100644 --- a/res/values-fa/strings.xml +++ b/res/values-fa/strings.xml @@ -168,6 +168,11 @@ "باز" "حذف نصب" "توقف اجباری" + "تنظیمات" + "%s سرویس به دستگاه شما دسترسی کامل دارند" + "%s سرویس دسترس‌پذیری به دستگاه شما دسترسی کامل دارند" + "%s می‌تواند صفحه، کنش‌ها و ورودی‌های شما را ببیند، کنش‌هایی را انجام دهد و نمایشگر را کنترل کند." + "این سرویس‌ها می‌توانند صفحه، کنش‌ها و ورودی‌های شما را ببینند، کنش‌هایی را انجام دهند و نمایشگر را کنترل کنند." "برنامه‌های پیش‌فرض" "هیچ برنامه پیش‌فرضی وجود ندارد." "پیش‌فرض برای کار" @@ -176,6 +181,7 @@ "دسترسی ویژه به برنامه" "عدم دسترسی ویژه به برنامه" "برنامه‌ای موجود نیست" + "برنامه همیار" "برنامه مرورگر" "برنامه تلفن" "برنامه پیامک" @@ -184,13 +190,13 @@ "برنامه موسیقی" "برنامه گالری" "برنامه تلفن حالت خودرو" - - + "فراخوانی برنامه هدایت" "برنامه غربالگری تماس" "برنامه همراه تماس" - "برنامه همیار" "برنامه طرح سه‌بعدی خودرو" + "از نمایه کاری پشتیبانی نمی‌کند" "توجه: اگر دستگاهتان را بازراه‌اندازی کنید و قفل صفحه تنظیم کرده باشید، تا قفل تلفن را باز نکنید، این برنامه نمی‌تواند شروع به کار کند." + "«دستیار» می‌تواند اطلاعات مربوط به برنامه‌های درحال استفاده در سیستم شما را بخواند، ازجمله اطلاعاتی که در صفحه‌نمایش شما قابل‌مشاهده است یا در برنامه‌ها قابل‌دسترسی است." "هم‌رسانی داده‌های اشکال‌زدایی" "جزئیات داده‌های اشکال‌زدایی هم‌رسانی شود؟" "%1$s می‌خواهد اطلاعات اشکال‌زدایی را بارگذاری کند." diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml index afb587423..a1a5eec84 100644 --- a/res/values-fi/strings.xml +++ b/res/values-fi/strings.xml @@ -168,6 +168,11 @@ "Avaa" "Poista" "Pakota sulkeutumaan" + "Asetukset" + "%s on saanut laitteen täydet käyttöoikeudet" + "%s esteettömyyspalvelulla on laitteen täydet käyttöoikeudet" + "%s voi nähdä näyttösi, toimintasi ja syöttämäsi tiedot, suorittaa toimintoja ja muuttaa näytön asetuksia." + "Nämä palvelut voivat nähdä näyttösi, toimintasi ja syöttämäsi tiedot, suorittaa toimintoja ja muuttaa näytön asetuksia." "Oletussovellukset" "Ei oletussovelluksia" "Työkäytön oletus" @@ -176,6 +181,7 @@ "Sovellusten erikoiskäyttö" "Ei sovellusten erikoiskäyttöä" "Ei sovelluksia" + "Avustajasovellus" "Selainsovellus" "Puhelin-sovellus" "Tekstiviestisovellus" @@ -184,13 +190,13 @@ "Musiikkisovellus" "Galleriasovellus" "Autotilan puhelinsovellus" - - + "Soitonsiirtosovellus" "Puhelujen suodatussovellus" "Puhelujen kumppanisovellus" - "Avustajasovellus" "Auton heijastussovellus" + "Ei tue työprofiilia" "Huomaa: Jos käynnistät laitteen uudelleen ja näytön lukitus on käytössä, sovellus voi käynnistyä vasta avattuasi lukituksen." + "Avustaja voi lukea tietoja järjestelmäsi käyttämistä sovelluksista, mukaan lukien tietoja, jotka näkyvät näytöllä tai jotka ovat käytettävissä sovelluksissa." "Jaa virheenkorjaustietoja" "Jaetaanko yksityiskohtaisia virheenkorjaustietoja?" "%1$s haluaa ladata virheenkorjaustietoja palvelimelle." diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml index e386d653e..ddd4ff904 100644 --- a/res/values-fr-rCA/strings.xml +++ b/res/values-fr-rCA/strings.xml @@ -168,6 +168,11 @@ "Ouvrir" "Désinstaller" "Forcer l\'arrêt" + "Paramètres" + "%s a un accès complet à votre appareil" + "%s services d\'accessibilité ont un accès complet à votre appareil" + "%s peut voir votre écran, vos actions et ce que vous entrez; il peut également effectuer des actions et contrôler l\'écran." + "Ces services peuvent voir votre écran, vos actions et ce que vous entrez; ils peuvent également effectuer des actions et contrôler l\'écran." "Applications par défaut" "Aucune application par défaut" "Par défaut pour util. profess." @@ -176,6 +181,7 @@ "Accès spécial pour applis" "Aucun accès spécial pour applis" "Aucune application" + "Application d\'assistance" "Application de navigateur" "Application Téléphone" "Application de messagerie texte" @@ -184,13 +190,13 @@ "Application de musique" "Application de galerie" "Appli tél. pour mode Voiture" - - + "Appeler l\'application de redirection" "Appli de filtrage des appels" "Application compagnon d\'appel" - "Application d\'assistance" "Appli de projection automobile" + "Non compatible avec les profils professionnels" "Remarque : Si vous redémarrez votre appareil et que vous avez défini un verrouillage de l\'écran, cette application ne pourra pas démarrer tant que vous n\'avez pas déverrouillé votre appareil" + "L\'Assistant Google pourra accéder aux données des applications en cours d\'utilisation sur votre système, y compris les données visibles à l\'écran ou accessibles au sein des applications." "Partager les données de débogage" "Partager des données de débogage détaillées?" "%1$s souhaite téléverser des données de débogage." diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index dad62bd4a..254fe62ea 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -168,6 +168,11 @@ "Ouvrir" "Désinstaller" "Forcer l\'arrêt" + "Paramètres" + "%s bénéficie d\'un accès complet à votre appareil" + "%s services d\'accessibilité bénéficient d\'un accès complet à votre appareil" + "%s peut voir votre écran, vos actions et ce que vous saisissez, réaliser des actions et contrôler l\'affichage." + "Ces services peuvent voir votre écran, vos actions, ce que vous saisissez, réaliser des actions et contrôler l\'affichage." "Applications par défaut" "Aucune application par défaut" "Par défaut pour utilisation pro" @@ -176,6 +181,7 @@ "Accès spécifique des applis" "Aucun accès spécif. des applis" "Aucune application" + "Application d\'assistance" "Application de navigateur" "Application Téléphone" "Application de SMS" @@ -184,13 +190,13 @@ "Application Musique" "Application Galerie" "Appli téléphone mode Voiture" - - + "Appli de redirection d\'appels" "Appli de filtrage des appels" "Application d\'appels associée" - "Application d\'assistance" "Appli Projection de la voiture" + "Non compatible avec le profil professionnel" "Remarque : Si vous redémarrez votre appareil et que le verrouillage de l\'écran est activé, vous ne pouvez pas lancer cette application tant que vous n\'avez pas déverrouillé votre appareil." + "L\'Assistant pourra accéder aux informations relatives aux applications en cours d\'utilisation sur votre système, y compris aux informations visibles à l\'écran ou accessibles dans les applications." "Partager les données de débogage" "Partager les données de débogage détaillées ?" "L\'application %1$s souhaite transférer des informations de débogage." diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml index 178840db4..0c688f00c 100644 --- a/res/values-gl/strings.xml +++ b/res/values-gl/strings.xml @@ -168,6 +168,11 @@ "Abrir" "Desinstalar" "Forzar parada" + "Configuración" + "%s ten acceso total ao teu dispositivo" + "%s servizos de accesibilidade teñen acceso total ao teu dispositivo" + "%s pode ver a túa pantalla, o que fas e o que introduces; realizar accións; e controlar a pantalla." + "Estes servizos poden ver a túa pantalla, o que fas e o que introduces; realizar accións; e controlar a pantalla." "Aplicacións predeterminadas" "Sen apps predeterminadas" "Predeterminadas para o traballo" @@ -176,21 +181,22 @@ "Acceso especial as aplicacións" "Sen acceso especial ás apps" "Non hai ningunha aplicación" + "Aplicación de asistencia" "Aplicación de navegador" "Aplicación de teléfono" "Aplicación de SMS" - "Aplicación para urxencias" + "Aplicación para emerxencias" "Aplicación de inicio" "Aplicación Música" "Aplicación Galería" "App de tel. do modo de cond." - - + "App de redirección de chamadas" "App de filtro de chamadas" "App complementaria de chamadas" - "Aplicación de asistencia" "App de proxección do coche" + "Non é compatible co perfil de traballo" "Nota: Se reinicias o dispositivo e definiches un bloqueo de pantalla, esta aplicación non se poderá iniciar ata que desbloquees o dispositivo." + "O asistente poderá ler información sobre as aplicacións en uso no teu sistema, incluídos os datos visibles na pantalla ou aos que se pode acceder desde as aplicacións." "Compartir datos de depuración" "Queres compartir datos detallados da depuración?" "A aplicación %1$s quere cargar información de depuración." diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml index 3ed31f8ca..e1b6f87b5 100644 --- a/res/values-gu/strings.xml +++ b/res/values-gu/strings.xml @@ -168,6 +168,11 @@ "ખોલો" "અનઇન્સ્ટૉલ કરો" "ફરજિયાત બંધ કરો" + "સેટિંગ" + "%s તમારા ડિવાઇસ માટે સંપૂર્ણ ઍક્સેસ ધરાવે છે" + "%s ઍક્સેસિબિલિટી સેવાઓ તમારા ડિવાઇસ માટે સંપૂર્ણ ઍક્સેસ ધરાવે છે" + "%s તમારી સ્ક્રીન, ક્રિયાઓ તેમજ ઇનપુટ જોઈ શકે છે, ક્રિયાઓ કરી શકે છે અને ડિસ્પ્લેનું નિયંત્રણ કરી શકે છે." + "આ સેવાઓ તમારી સ્ક્રીન, ક્રિયાઓ તેમજ ઇનપુટ જોઈ શકે છે, ક્રિયાઓ કરી શકે છે અને ડિસ્પ્લેનું નિયંત્રણ કરી શકે છે." "ડિફૉલ્ટ ઍપ" "કોઈ ડિફૉલ્ટ ઍપ નથી" "કાર્ય માટે ડિફૉલ્ટ" @@ -176,6 +181,7 @@ "વિશેષ ઍપનો ઍક્સેસ" "કોઈ વિશેષ ઍપનો ઍક્સેસ નથી" "કોઈ ઍપ નથી" + "સહાયક ઍપ્લિકેશન" "બ્રાઉઝર ઍપ" "ફોન ઍપ" "SMS ઍપ" @@ -184,13 +190,13 @@ "મ્યુઝિક ઍપ" "ગૅલેરી ઍપ" "કાર મોડ ફોન ઍપ" - - + "કૉલ રીડાયરેક્ટ કરનારી ઍપ" "કૉલ સ્ક્રીનિંગ ઍપ" "કૉલ સાથી ઍપ" - "સહાયક ઍપ્લિકેશન" "કાર પ્રોજેક્શન ઍપ" + "કાર્યાલયની પ્રોફાઇલનું સમર્થન કરતી નથી" "નોંધ: જો તમે તમારું ડિવાઇસ ફરીથી શરૂ કરો અને કોઈ સ્ક્રીન લૉક સેટ કરેલું હોય, તો જ્યાં સુધી તમે તમારું ડિવાઇસ અનલૉક નહીં કરો ત્યાં સુધી આ ઍપ શરૂ થઈ શકશે નહીં." + "આસિસ્ટંટ તમારી સ્ક્રીન પર જોઈ શકાતી અથવા ઍપમાંથી ઍક્સેસ કરી શકાય તેવી માહિતી સહિતની તમારી સિસ્ટમમાં ઉપયોગમાં લેવાતી ઍપ વિશેની માહિતી વાંચી શકશે." "ડિબગીંગ ડેટા શેર કરો" "વિગતવાર ડિબગીંગ ડેટા શેર કરીએ?" "%1$s, ડિબગીંગ માહિતી અપલોડ કરવા માગે છે" diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml index 5b17b304f..61927d1ad 100644 --- a/res/values-hi/strings.xml +++ b/res/values-hi/strings.xml @@ -168,6 +168,16 @@ "खोलें" "अनइंस्टॉल करें" "ज़बरदस्ती रोकें" + + + + + + + + + + "डिफ़ॉल्ट ऐप्लिकेशन" "कोई डिफ़ॉल्ट ऐप्लिकेशन नहीं." "काम के लिए डिफ़ॉल्ट" @@ -176,6 +186,7 @@ "ऐप्लिकेशन को खास अनुमति" "ऐप्लिकेशन को खास अनुमति नहीं" "कोई ऐप्लिकेशन नहीं" + "सहायक ऐप्लिकेशन" "ब्राउज़र ऐप्लिकेशन" "फ़ोन ऐप्लिकेशन" "मैसेज (एसएमएस) ऐप्लिकेशन" @@ -184,13 +195,15 @@ "संगीत ऐप्लिकेशन" "गैलरी ऐप्लिकेशन" "कार मोड वाला फ़ोन ऐप्लिकेशन" - - + "कॉल रीडायरेक्ट करने वाला ऐप" "कॉल की स्क्रीनिंग का ऐप्लिकेशन" "कॉल करने का साथी ऐप्लिकेशन" - "सहायक ऐप्लिकेशन" "कार प्रोजेक्शन ऐप्लिकेशन" + + "ध्यान दें : अगर डिवाइस को रीस्टार्ट करते समय उसकी स्क्रीन लॉक है, तो यह ऐप्लिकेशन तब तक शुरू नहीं होगा, जब तक आप डिवाइस को अनलॉक नहीं करते." + + "डीबग करने की प्रक्रिया का डेटा शेयर करें" "डीबग करने की ज़्यादा जानकारी शेयर करना चाहते हैं?" "%1$s डीबग करने की जानकारी अपलोड करना चाहता है." diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml index 4bd137834..a47153a0c 100644 --- a/res/values-hr/strings.xml +++ b/res/values-hr/strings.xml @@ -173,6 +173,11 @@ "Otvori" "Deinstaliraj" "Prisilno zaustavi" + "Postavke" + "%s ima potpuni pristup uređaju" + "Usluge pristupačnosti s potpunim pristupom uređaju (%s)" + "%s može vidjeti vaš zaslon, radnje i unose, izvršavati radnje i upravljati zaslonom." + "Te usluge mogu vidjeti vaš zaslon, radnje i unose, izvršavati radnje i upravljati zaslonom." "Zadane aplikacije" "Nema zadanih aplikacija" "Zadano za posao" @@ -181,6 +186,7 @@ "Poseban pristup aplikaciji" "Bez poseb. pristupa aplikaciji" "Nema aplikacija" + "Aplikacija pomoćnik" "Aplikacija preglednika" "Aplikacija Telefon" "Aplikacija za SMS" @@ -189,13 +195,13 @@ "Aplikacija Glazba" "Aplikacija Galerija" "Ap. za način rada u automobilu" - - + "Apl. za preusmjeravanje poziva" "Ap. za filtriranje poziva" "Popratna aplikacija za pozive" - "Aplikacija pomoćnik" "Apl. Projekcija u automobilu" + "Ne podržava radni profil" "Napomena: ako ponovo pokrenete uređaj, a na njemu je postavljeno zaključavanje zaslona, ova se aplikacija ne može pokrenuti dok ne otključate uređaj." + "Pomoćnik će moći čitati podatke o aplikacijama koje se upotrebljavaju na vašem sustavu, uključujući podatke vidljive na zaslonu ili podatke kojima se može pristupiti u aplikacijama." "Dijeli podatke o otklanjanju pogrešaka" "Dijeliti detaljne podatke o otklanjanju pogrešaka?" "%1$s želi prenijeti informacije o otklanjanju pogrešaka." diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml index 41984a807..26ea52b79 100644 --- a/res/values-hu/strings.xml +++ b/res/values-hu/strings.xml @@ -168,6 +168,11 @@ "Megnyitás" "Eltávolítás" "Mindenképp álljon le" + "Beállítások" + "A(z) %s teljes körű hozzáféréssel rendelkezik az eszközhöz" + "%s kisegítő szolgáltatás teljes körű hozzáféréssel rendelkezik az eszközhöz" + "A(z) %s megtekintheti a képernyőt, a műveleteket és a beviteleket, műveleteket végezhet, és vezérelheti a képernyőt." + "Ezek a szolgáltatások megtekinthetik a képernyőt, a műveleteket és a beviteleket, műveleteket végezhetnek, és vezérelhetik a képernyőt." "Alapértelmezett alkalmazások" "Nincsenek alapértelmezettek" "Munkahelyi alapértelmezett" @@ -176,6 +181,7 @@ "Különleges alkalmazás-hozzáférés" "Nincs különleges hozzáférés" "Nincs alkalmazás" + "Segédalkalmazás" "Böngésző" "Telefon alkalmazás" "SMS-küldő" @@ -184,13 +190,13 @@ "Zenealkalmazás" "Galériaalkalmazás" "Telefonalkalmazás autós módhoz" - - + "Hívásátirányító alkalmazás" "Hívásszűrő alkalmazás" "Társalkalmazás hívásokhoz" - "Segédalkalmazás" "Autós kivetítő alkalmazás" + "Az alkalmazás nem támogatja a munkaprofilt" "Megjegyzés: Ha újraindítja az eszközt, és képernyőzárat állított be, ez az alkalmazás csak a telefon feloldását követően indul el." + "A segéd hozzáfér majd a rendszer éppen használatban lévő alkalmazásainak információihoz, beleértve a képernyőn megjelenő vagy az alkalmazásokban hozzáférhető információkat is." "Hibakeresési adatok megosztása" "Megosztja a részletes hibakeresési adatokat?" "A(z) %1$s hibakeresési adatokat szeretne feltölteni." diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml index 7255a7012..24360946d 100644 --- a/res/values-hy/strings.xml +++ b/res/values-hy/strings.xml @@ -168,6 +168,16 @@ "Բացել" "Ապատեղադրել" "Ստիպողաբար դադարեցնել" + + + + + + + + + + "Կանխադրված հավելվածներ" "Կանխադրված հավելվածներ չկան" "Կանխադրված՝ աշխատանքի համար" @@ -176,6 +186,7 @@ "Հատուկ հասանելիություն" "Հատուկ հասանելիություն չկա" "Հավելվածներ չկան" + "Օգնական հավելված" "«Դիտարկիչ» հավելված" "«Հեռախոս» հավելված" "«SMS» հավելված" @@ -184,13 +195,15 @@ "Երաժշտություն" "Ցուցասրահ" "«Հեռախոս» մեքենայի ռեժիմի համար" - - + "Զանգի վերահասցեավորման հավելված" "Հավելված զանգերի զտման համար" "Ուղեկցող հավելված զանգերի համար" - "Օգնական հավելված" "Հեռարձակում մեքենայի էկրանին" + + "Ուշադրություն. եթե դուք վերագործարկեք ձեր սարքը, որում սահմանված է էկրանի կողպում, այս հավելվածը չի աշխատի, մինչև չապակողպեք սարքը։" + + "Վրիպազերծման տվյալների ուղարկում" "Ուղարկե՞լ վրիպազերծման մանրամասն տվյալները" "%1$s-ն ուզում է վերբեռնել վրիպազերծման տվյալները:" diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml index 8d5631df2..03ae84a10 100644 --- a/res/values-in/strings.xml +++ b/res/values-in/strings.xml @@ -168,6 +168,11 @@ "Buka" "Uninstal" "Paksa berhenti" + "Setelan" + "%s memiliki akses penuh ke perangkat Anda" + "Layanan aksesibilitas %s memiliki akses penuh ke perangkat Anda" + "%s dapat melihat layar, tindakan, dan masukan Anda, serta dapat melakukan tindakan dan mengontrol tampilan." + "Layanan ini dapat melihat layar, tindakan, dan masukan Anda, serta dapat melakukan tindakan dan mengontrol tampilan." "Aplikasi default" "Tidak ada aplikasi default" "Default untuk kerja" @@ -176,6 +181,7 @@ "Akses aplikasi khusus" "Tidak ada akses apl khusus" "Tidak ada aplikasi" + "Aplikasi bantuan" "Aplikasi browser" "Aplikasi telepon" "Aplikasi SMS" @@ -184,13 +190,13 @@ "Aplikasi Musik" "Aplikasi Galeri" "Aplikasi telepon mode mobil" - - + "Aplikasi pengalihan panggilan" "Aplikasi penyaringan telepon" "Aplikasi pendamping telepon" - "Aplikasi bantuan" "Aplikasi Proyeksi Mobil" + "Tidak mendukung profil kerja" "Catatan: Jika Anda memulai ulang perangkat dan menyetel kunci layar, aplikasi ini tidak dapat dimulai hingga Anda membuka kunci perangkat Anda." + "Asisten dapat membaca informasi tentang aplikasi yang sedang digunakan di sistem, termasuk informasi yang terlihat di layar atau dapat diakses dalam aplikasi." "Bagikan Data Proses Debug" "Bagikan data proses debug yang mendetail?" "%1$s ingin mengupload informasi proses debug." diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml index d72890a7d..1870106be 100644 --- a/res/values-is/strings.xml +++ b/res/values-is/strings.xml @@ -168,6 +168,11 @@ "Opna" "Fjarlægja" "Þvinga lokun" + "Stillingar" + "%s hefur fullan aðgang að tækinu þínu" + "%s aðgengisþjónustur hafa fullan aðgang að tækinu þínu" + "%s getur skoðað skjáinn þinn, aðgerðir og innslátt, framkvæmt aðgerðir og stjórnað skjánum." + "Þessar þjónustur geta skoðað skjáinn þinn, aðgerðir og innslátt, framkvæmt aðgerðir og stjórnað skjánum." "Sjálfgefin forrit" "Engin sjálfgefin forrit" "Sjálfgefið fyrir vinnu" @@ -176,6 +181,7 @@ "Sérstakur forritaaðgangur" "Enginn sérstakur forritaaðgangur" "Engin forrit" + "Aðstoðarforrit" "Vafraforrit" "Símaforrit" "SMS-forrit" @@ -184,13 +190,13 @@ "Tónlistarforrit" "Myndasafnsforrit" "Símaforrit í bílastillingu" - - + "Símtalsflutningaforrit" "Símtalasíuforrit" "Fylgiforrit fyrir símtöl" - "Aðstoðarforrit" "Forrit fyrir vörpun bíls" + "Styður ekki vinnusnið" "Athugaðu: Ef þú endurræsir tækið og það er með skjálás er ekki hægt að ræsa þetta forrit fyrr en þú tekur tækið úr lás." + "Hjálparinn mun geta séð upplýsingar um forrit í notkun í kerfinu þínu, þar á meðal upplýsingar sem sjást á skjánum eða eru aðgengilegar úr forritum." "Deila villuleitargögnum" "Viltu deila ítarlegum villuleitargögnum?" "%1$s vill hlaða inn upplýsingum um villuleit." diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml index 98d6f614e..2a65ee473 100644 --- a/res/values-it/strings.xml +++ b/res/values-it/strings.xml @@ -168,6 +168,11 @@ "Apri" "Disinstalla" "Forza interruzione" + "Impostazioni" + "%s ha accesso completo al tuo dispositivo" + "%s servizi di accessibilità hanno accesso completo al tuo dispositivo" + "%s può vedere il tuo schermo, le tue azioni e i tuoi inserimenti, compiere azioni e controllare il display." + "Questi servizi possono vedere il tuo schermo, le tue azioni e i tuoi inserimenti, compiere azioni e controllare il display." "App predefinite" "Nessuna app predefinita" "Predefinite per il lavoro" @@ -176,6 +181,7 @@ "Accesso speciale alle app" "Nessun accesso speciale ad app" "Nessuna app" + "App di assistenza" "App browser" "App Telefono" "App per SMS" @@ -184,13 +190,13 @@ "App per la musica" "App Galleria" "App telefono modalità auto" - - + "App reindirizzamento chiamate" "App per screening chiamate" "App complementare chiamate" - "App di assistenza" "App di proiezione dell\'auto" + "Il profilo di lavoro non è supportato" "Nota: se riavvii il dispositivo ed è impostato un blocco schermo, sarà possibile avviare l\'app soltanto dopo aver sbloccato il dispositivo." + "L\'assistente potrà leggere informazioni sulle app in uso nel sistema, incluse le informazioni visibili sullo schermo o accessibili all\'interno delle app." "Condividi dati di debug" "Condividere i dati di debug dettagliati?" "L\'app %1$s vorrebbe caricare informazioni di debug." diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml index 05e057348..8bbc4f41c 100644 --- a/res/values-iw/strings.xml +++ b/res/values-iw/strings.xml @@ -178,6 +178,11 @@ "פתיחה" "הסרת התקנה" "סגירה ידנית" + "הגדרות" + "לשירות %s יש גישה מלאה למכשיר שלך" + "ל-%s שירותי נגישות יש גישה מלאה למכשיר שלך" + "השירות %s יכול להציג את המסך, הפעולות ופריטי הפלט שלך, וכן לבצע פעולות ולשלוט בתצוגה." + "השירותים האלה יכולים להציג את המסך, הפעולות ופריטי הפלט שלך, וכן לבצע פעולות ולשלוט בתצוגה." "אפליקציות ברירת מחדל" "אין אפליקציות ברירת מחדל" "ברירת מחדל לעבודה" @@ -186,6 +191,7 @@ "גישה מיוחדת לאפליקציה" "אין גישה מיוחדת לאפליקציה" "אין אפליקציות" + "אפליקציית עזרה" "אפליקציית דפדפן" "אפליקציית \'טלפון\'" "‏אפליקציית SMS" @@ -194,13 +200,13 @@ "אפליקציית מוזיקה" "גלריית האפליקציות" "אפליקציית \'טלפון\' במצב נהיגה" - - + "אפליקציה להפניית שיחות" "אפליקציה לסינון שיחות" "אפליקציה נלווית לשיחות" - "אפליקציית עזרה" "אפליקציית ההקרנה של הרכב" + "לא תומכת בפרופיל עבודה" "הערה: אם ביצעת הפעלה מחדש למכשיר ונעילת המסך מוגדרת, ניתן יהיה להפעיל את האפליקציה הזו רק לאחר ביטול נעילת המכשיר." + "‏ה-Assistant יוכל לקרוא מידע על אפליקציות שבהן נעשה שימוש במערכת שלך, כולל מידע המופיע במסך או שניתן לגשת אליו באפליקציות." "שיתוף נתונים של ניפוי באגים" "לשתף נתונים מפורטים של ניפוי באגים?" "האפליקציה %1$s מבקשת להעלות נתונים של ניפוי באגים." diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml index 2b3d711d8..cd0307402 100644 --- a/res/values-ja/strings.xml +++ b/res/values-ja/strings.xml @@ -168,6 +168,11 @@ "開く" "アンインストール" "強制停止" + "設定" + "%s にデバイスへのフルアクセスを許可" + "%s 件のユーザー補助サービスにデバイスへのフルアクセスを許可" + "%s に、画面、アクション、入力の読み取り、アクションの実行、ディスプレイの操作を許可しています。" + "これらのサービスに、画面、アクション、入力の読み取り、アクションの実行、ディスプレイの操作を許可しています。" "デフォルトのアプリ" "デフォルトのアプリはありません" "デフォルトの仕事用アプリ" @@ -176,6 +181,7 @@ "特別なアプリアクセス" "特別なアプリアクセスなし" "アプリなし" + "アシストアプリ" "ブラウザアプリ" "電話アプリ" "SMS アプリ" @@ -184,13 +190,13 @@ "音楽アプリ" "ギャラリー アプリ" "運転モード電話アプリ" - - + "通話転送アプリ" "通話スクリーニング アプリ" "通話コンパニオン アプリ" - "アシストアプリ" "車での投影アプリ" + "仕事用プロファイルをサポートしていません" "注: デバイスを再起動したときに画面ロックが設定されている場合は、デバイスのロックを解除するまでこのアプリを起動できません。" + "アシスタントはシステムで使用中のアプリに関する情報(画面に表示される情報、アプリ内でアクセス可能な情報など)を読み取れるようになります。" "デバッグデータの共有" "詳細なデバッグデータを共有しますか?" "%1$s がデバッグ情報のアップロードをリクエストしています。" diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml index c09d834d1..8c414d0ab 100644 --- a/res/values-ka/strings.xml +++ b/res/values-ka/strings.xml @@ -168,6 +168,16 @@ "გახსნა" "დეინსტალაცია" "იძულებით შეწყვეტა" + + + + + + + + + + "ნაგულისხმევი აპები" "ნაგულისხმევი აპები არ არის" "ნაგულისხმევი სამსახურისთვის" @@ -176,6 +186,7 @@ "აპების სპეციალური წვდომა" "აპების სპეციალური წვდომა არაა" "აპები არ არის" + "დამხმარე აპი" "ბრაუზერის აპი" "ტელეფონის აპი" "SMS აპი" @@ -184,13 +195,15 @@ "მუსიკის აპი" "გალერეის აპი" "მანქანის რეჟიმის სატელეფ. აპი" - - + "ზარების გადამისამართების აპი" "ზარების გაფილტვრის აპი" "დარეკვის კომპანიონი აპი" - "დამხმარე აპი" "მანქანაში პროეცირების აპი" + + "შენიშვნა: თუ ეკრანის დაბლოკვის მეთოდს იყენებთ, მოწყობილობის გადატვირთვის შემდეგ ეს აპი ვერ გაეშვება, სანამ მოწყობილობას არ განბლოკავთ" + + "გამართვის მონაცემების გაზიარება" "გსურთ გამართვის დეტალური მონაცემების გაზიარება?" "%1$s ითხოვს გამართვის ინფორმაციის ატვირთვას." diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml index ee8dc870d..879e6e393 100644 --- a/res/values-kk/strings.xml +++ b/res/values-kk/strings.xml @@ -168,6 +168,16 @@ "Ашу" "Жою" "Қолмен тоқтату" + + + + + + + + + + "Әдепкі қолданбалар" "Әдепкі қолданбалар жоқ" "Жұмыс үшін әдепкі қолданба" @@ -176,6 +186,7 @@ "Арнайы кіру" "Арнайы кіру мүмкіндігі жоқ" "Қолданбалар жоқ" + "Көмекші қолданба" "Браузер қолданбасы" "Телефон қолданбасы" "SMS қолданбасы" @@ -184,13 +195,15 @@ "Музыка қолданбасы" "Галерея қолданбасы" "Көлік режиміндегі қоңырауларға арналған қолданба" - - + "Қоңырау бағытын ауыстыру" "Қоңырауды тексеру қолданбасы" "Қоңырауға арналған қосымша қолданба" - "Көмекші қолданба" "Көлік экранына шығару" + + "Ескертпе: Құрылғыңызды қайта қоссаңыз және экран құлыпталса, құрылғының құлпы ашылмайынша, қолданба іске қосылмайды." + + "Түзету туралы деректерді бөлісу" "Түзету туралы толығырақ деректер бөлісілсін бе?" "%1$s қолданбасы түзету туралы ақпаратты жүктеп салғысы келеді." diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml index 35b789e9b..a7cc91ccf 100644 --- a/res/values-km/strings.xml +++ b/res/values-km/strings.xml @@ -168,6 +168,16 @@ "បើក" "លុប" "បង្ខំ​ឱ្យ​បញ្ឈប់" + + + + + + + + + + "កម្មវិធី​លំនាំដើម" "គ្មានកម្មវិធីលំនាំដើមទេ" "លំនាំដើម​សម្រាប់ការងារ" @@ -176,6 +186,7 @@ "ការចូលប្រើកម្មវិធីពិសេស" "គ្មានការចូលប្រើ​កម្មវិធី​ពិសេសទេ" "គ្មានកម្មវិធី​ទេ​" + "កម្មវិធី​ជំនួយ" "កម្មវិធីរុករកតាមអ៊ីនធឺណិត" "កម្មវិធីទូរសព្ទ" "កម្មវិធីផ្ញើសារ SMS" @@ -184,13 +195,15 @@ "កម្មវិធី​តន្រី្ត" "កម្មវិធីសាល​រូបភាព" "កម្មវិធី​ទូរសព្ទ​នៃមុខងារ​រថយន្ត" - - + "កម្មវិធី​បញ្ជូនបន្ត​ការហៅទូរសព្ទ" "កម្មវិធីត្រួតពិនិត្យការហៅទូរសព្ទ" "កម្មវិធី​ដៃគូ​សម្រាប់​ហៅទូរសព្ទ" - "កម្មវិធី​ជំនួយ" "កម្មវិធី​បញ្ចាំង​របស់​រថយន្ត" + + "ចំណាំ៖ ប្រសិនបើ​អ្នកចាប់ផ្ដើម​ឧបករណ៍​​របស់អ្នក​ឡើងវិញ និងបានកំណត់​ការចាក់សោ​អេក្រង់ កម្មវិធីនេះ​មិនអាច​ចាប់ផ្តើម​បានទេ រហូតទាល់តែ​អ្នកដោះសោ​ឧបករណ៍របស់អ្នក។" + + "ចែករំលែក​ទិន្នន័យ​នៃការ​ជួសជុល" "ចែករំលែក​ទិន្នន័យ​លម្អិត​នៃការជួសជុល?" "%1$s ចង់​បង្ហោះ​ព័ត៌មាននៃ​ការជួសជុល។" diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml index 91e8a6f29..2c454bff3 100644 --- a/res/values-kn/strings.xml +++ b/res/values-kn/strings.xml @@ -168,6 +168,16 @@ "ತೆರೆ" "ಅನ್‌ಇನ್‌ಸ್ಟಾಲ್" "ಬಲವಂತವಾಗಿ ನಿಲ್ಲಿಸಿ" + + + + + + + + + + "ಡೀಫಾಲ್ಟ್ ಆ್ಯಪ್‌ಗಳು" "ಯಾವುದೇ ಡೀಫಾಲ್ಟ್‌ ಆ್ಯಪ್‌ಗಳಿಲ್ಲ" "ಕೆಲಸದ ಕುರಿತಾದ ಡೀಫಾಲ್ಟ್ ಆ್ಯಪ್" @@ -176,6 +186,7 @@ "ಆ್ಯಪ್‌ಗೆ ವಿಶೇಷ ಪ್ರವೇಶ" "ಆ್ಯಪ್‌ಗೆ ವಿಶೇಷ ಪ್ರವೇಶವಿಲ್ಲ" "ಯಾವುದೇ ಆ್ಯಪ್‌ಗಳು ಇಲ್ಲ" + "ಅಸಿಸ್ಟೆಂಟ್ ಆ್ಯಪ್‌" "ಬ್ರೌಸರ್ ಆ್ಯಪ್" "ಫೋನ್ ಆ್ಯಪ್" "ಎಸ್ಎಂಎಸ್ ಆ್ಯಪ್" @@ -184,13 +195,15 @@ "ಸಂಗೀತ ಆ್ಯಪ್‌" "ಗ್ಯಾಲರಿ ಆ್ಯಪ್‌" "ಕಾರ್‌ ಮೋಡ್‌ ಫೋನ್‌ ಆ್ಯಪ್" - - + "ಕರೆ ಮರುನಿರ್ದೇಶನ ಆ್ಯಪ್‌" "ಕರೆ ಸ್ಕ್ರೀನಿಂಗ್ ಆ್ಯಪ್" "ಕರೆ ಕಂಪ್ಯಾನಿಯನ್ ಆ್ಯಪ್" - "ಅಸಿಸ್ಟೆಂಟ್ ಆ್ಯಪ್‌" "ಕಾರ್ ಪ್ರೊಜೆಕ್ಷನ್ ಆ್ಯಪ್‌" + + "ಗಮನಿಸಿ: ನೀವು ನಿಮ್ಮ ಸಾಧನವನ್ನು ಮರುಪ್ರಾರಂಭಿಸಿದಲ್ಲಿ ಮತ್ತು ಪರದೆಯ ಲಾಕ್‌ ಹೊಂದಿದ್ದರೆ, ನಿಮ್ಮ ಸಾಧನವನ್ನು ಅನ್‌ಲಾಕ್‌ ಮಾಡುವವರೆಗೂ ಈ ಆ್ಯಪ್‌ ಅನ್ನು ಪ್ರಾರಂಭಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ" + + "ಡೀಬಗ್ ಮಾಡುವಿಕೆ ಡೇಟಾವನ್ನು ಹಂಚಿಕೊಳ್ಳಿ" "ವಿವರವಾದ ಡೀಬಗ್ ಮಾಡುವಿಕೆಯ ಡೇಟಾವನ್ನು ಹಂಚಿಕೊಳ್ಳಬೇಕೆ?" "%1$s ಆ್ಯಪ್, ಡೀಬಗ್ ಮಾಡುವಿಕೆಯ ಮಾಹಿತಿಯನ್ನು ಅಪ್‌ಲೋಡ್ ಮಾಡಲು ಬಯಸುತ್ತದೆ." diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml index f84d91bb1..9ff2d7fc6 100644 --- a/res/values-ko/strings.xml +++ b/res/values-ko/strings.xml @@ -168,6 +168,16 @@ "열기" "제거" "강제 종료" + + + + + + + + + + "기본 앱" "기본 앱 없음" "직장용 기본 앱" @@ -176,6 +186,7 @@ "특수 앱 액세스 권한" "특수 앱 액세스 권한 없음" "앱 없음" + "지원 앱" "브라우저 앱" "전화 앱" "SMS 앱" @@ -184,13 +195,15 @@ "음악 앱" "갤러리 앱" "자동차 모드 전화 앱" - - + "통화 리디렉션 앱" "통화 선택 앱" "통화 호환 앱" - "지원 앱" "차량 프로젝션 앱" + + "참고: 화면 잠금이 설정되어 있다면 기기를 다시 시작한 후 이 앱을 시작하려면 기기를 잠금 해제해야 합니다." + + "디버깅 데이터 공유" "상세한 디버깅 데이터를 공유하시겠습니까?" "%1$s에서 디버깅 정보를 업로드하려고 합니다." diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml index b06085dfb..3caaa4ce7 100644 --- a/res/values-ky/strings.xml +++ b/res/values-ky/strings.xml @@ -168,6 +168,16 @@ "Ачуу" "Чыгарып салуу" "Мажбурлап токтотуу" + + + + + + + + + + "Демейки колдонмолор" "Демейки колдонмолор жок" "Жумуш үчүн демейки жөндөөлөр" @@ -176,6 +186,7 @@ "Колдонмонун атайын уруксаты" "Колднмнун атайын уруксаты жок" "Бир да колдонмо жок" + "Көмөкчү колдонмо" "\"Серепчи\" колдонмосу" "¨Телефон\" колдонмосу" "\"SMS\" колдонмосу" @@ -184,13 +195,15 @@ "Музыка колдонмосу" "Галерея колдонмосу" "Унаа режиминдеги \"Телефон\" колдонмосу" - - + "Чалууну багытточу колдонмо" "Чалууларды башкаруу колдонмосу" "Чалууга коштомо колдонмо" - "Көмөкчү колдонмо" "Унааны долбоорлоо колдонмосу" + + "Эскертүү: Эгер түзмөгүңүздү өчүрүп күйгүзгөндө экранды бөгөттөө жөндөлгөн болсо, түзмөктү бөгөттөн чыгармайынча бул колдонмо ачылбайт." + + "Мүчүлүштүктөрдү оңдоо дайындарын бөлүшүү" "Мүчүлүштүктөрдү оңдоо дайындары бөлүшүлсүнбү?" "%1$s мүчүлүштүктөрдү оңдоо маалыматын жүктөп бергиси келет." diff --git a/res/values-lo/strings.xml b/res/values-lo/strings.xml index 3b4cfaee7..d8185aa2e 100644 --- a/res/values-lo/strings.xml +++ b/res/values-lo/strings.xml @@ -168,6 +168,11 @@ "ເປີດ" "ຖອນການຕິດຕັ້ງ" "ບັງຄັບຢຸດ" + "ການຕັ້ງຄ່າ" + "%s ມີສິດເຂົ້າເຖິງອຸປະກອນຂອງທ່ານເຕັມຮູບແບບ" + "%s ບໍລິການຊ່ວຍເຂົ້າເຖິງມີສິດເຂົ້າເຖິງອຸປະກອນຂອງທ່ານເຕັມຮູບແບບ" + "%s ສາມາດເບິ່ງໜ້າຈໍ, ຄຳສັ່ງ ແລະ ການປ້ອນຂໍ້ມູນຂອງທ່ານ, ໃຊ້ຄຳສັ່ງ ແລະ ຄວບຄຸມການສະແດງຜົນໄດ້." + "ບໍລິການເຫຼົ່ານີ້ສາມາດເບິ່ງໜ້າຈໍ, ຄຳສັ່ງ ແລະ ການປ້ອນຂໍ້ມູນຂອງທ່ານ, ໃຊ້ຄຳສັ່ງ ແລະ ຄວບຄຸມການສະແດງຜົນໄດ້." "ແອັບເລີ່ມຕົ້ນ" "ບໍ່ມີແອັບເລີ່ມຕົ້ນ" "ຄ່າເລີ່ມຕົ້ນສຳລັບບ່ອນເຮັດວຽກ" @@ -176,6 +181,7 @@ "ສິດການເຂົ້າເຖິງແອັບພິເສດ" "ບໍ່ມີສິດການເຂົ້າເຖິງແອັບພິເສດ" "ບໍ່ມີແອັບ" + "ແອັບຜູ້ຊ່ວຍ" "ແອັບໂປຣແກຣມທ່ອງເວັບ" "ແອັບໂທລະສັບ" "ແອັບ SMS" @@ -184,13 +190,13 @@ "ແອັບເພງ" "ແອັບຄັງ" "ແອັບໂທລະສັບໂໝດລົດ" - - + "ແອັບການປ່ຽນເສັ້ນທາງສາຍ" "ແອັບກວດສອບການໂທ" "ແອັບແຖມການໂທ" - "ແອັບຜູ້ຊ່ວຍ" "ແອັບ Car Projection" + "ບໍ່ຮອງຮັບໂປຣໄຟລ໌ບ່ອນເຮັດວຽກ" "ໝາຍເຫດ: ຫາກທ່ານຣີສະຕາດອຸປະກອນຂອງທ່ານ ແລະ ຕັ້ງການລັອກໜ້າຈໍໄວ້, ແອັບນີ້ຈະບໍ່ສາມາດໃຊ້ໄດ້ຈົນກວ່າທ່ານຈະປົດລັອກອຸປະກອນຂອງທ່ານ." + "ຜູ້ຊ່ວຍຈະສາມາດອ່ານຂໍ້ມູນກ່ຽວກັບແອັບທີ່ໃຊ້ໃນລະບົບຂອງທ່ານ ຮວມທັງຂໍ້ມູນທີ່ເບິ່ງເຫັນໄດ້ໃນໜ້າຈໍຂອງທ່ານ ຫຼື ເຂົ້າເຖິງໄດ້ພາຍໃນແອັບນັ້ນ." "ແບ່ງປັນຂໍ້ມູນການດີບັກ" "ແບ່ງປັນຂໍ້ມູນການດີບັກແບບລະອຽດບໍ?" "%1$s ຕ້ອງການອັບໂຫລດຂໍ້ມູນການດີບັກ." diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml index 18c1711f7..82ab2fe83 100644 --- a/res/values-lt/strings.xml +++ b/res/values-lt/strings.xml @@ -178,6 +178,11 @@ "Atidaryti" "Pašalinti" "Priverstinai sustabdyti" + "Nustatymai" + "„%s“ suteikta visateisė prieiga prie jūsų įrenginio" + "%s pritaikymo neįgaliesiems pasl. suteikta visateisė prieiga prie jūsų įrenginio" + "„%s“ gali peržiūrėti jūsų ekraną, veiksmus ir įvestis, atlikti veiksmus ir valdyti ekraną." + "Šios paslaugos gali peržiūrėti jūsų ekraną, veiksmus ir įvestis, atlikti veiksmus ir valdyti ekraną." "Numatytosios programos" "Nėra jokių numatytųjų programų" "Numatytosios darbo programos" @@ -186,6 +191,7 @@ "Speciali prieiga prie programų" "Nėra spec. prieig. prie progr." "Nėra jokių programų" + "Pagalbinė programa" "Naršyklės programa" "Telefono programa" "SMS programa" @@ -194,13 +200,13 @@ "Muzikos programa" "Galerijos programa" "Automob. režimo tel. programa" - - + "Skambučių peradres. programa" "Skambučių stebėjimo programa" "Papild. programos iškvietimas" - "Pagalbinė programa" "Automob. projekcijos programa" + "Nepalaikomas darbo profilis" "Pastaba. Jei esate nustatę ekrano užraktą ir iš naujo paleisite įrenginį, nebus galima atidaryti programos, kol neatrakinsite įrenginio." + "Padėjėjas galės skaityti informaciją apie sistemoje naudojamas programas, įskaitant ekrane matomą ar programose pasiekiamą informaciją." "Derinimo duomenų bendrinimas" "Bendrinti išsamius derinimo duomenis?" "Programa „%1$s“ norėtų įkelti derinimo informaciją." diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml index 24899fe4e..e70e4c16c 100644 --- a/res/values-lv/strings.xml +++ b/res/values-lv/strings.xml @@ -173,6 +173,11 @@ "Atvērt" "Atinstalēt" "Apturēt piespiedu kārtā" + "Iestatījumi" + "Pakalpojumam %s ir pilna piekļuve jūsu ierīcei" + "%s pieejamības pakalpojumiem ir pilna piekļuve jūsu ierīcei" + "Pakalpojums %s var skatīt jūsu ekrānu, darbības un ievadīto informāciju, kā arī veikt darbības un kontrolēt attēlojumu displejā." + "Šie pakalpojumi var skatīt jūsu ekrānu, darbības un ievadīto informāciju, kā arī veikt darbības un kontrolēt attēlojumu displejā." "Noklusējuma lietotnes" "Nav noklusējuma lietotņu" "Noklusējuma iestatījums darbam" @@ -181,6 +186,7 @@ "Īpaša piekļuve lietotnēm" "Nav īpašas piekļuves lietotnēm" "Nav lietotņu" + "Palīga lietotne" "Pārlūkprogrammas lietotne" "Lietotne Tālrunis" "Īsziņu lietotne" @@ -189,13 +195,13 @@ "Mūzikas lietotne" "Galerijas lietotne" "Auto režīma tālruņu lietotne" - - + "Zvanu novirzīšanas lietotne" "Zvanu pārvaldības lietotne" "Zvanu palīglietotne" - "Palīga lietotne" "Projicēš. automašīnā lietotne" + "Darba profils netiek atbalstīts" "Piezīme. Ja esat iestatījis ekrāna bloķēšanu un restartēsiet ierīci, šo lietotni varēs startēt tikai pēc ierīces atbloķēšanas." + "Asistents varēs lasīt informāciju par jūsu sistēmā izmantotajām lietotnēm, tostarp jūsu ekrānā redzamo informāciju vai lietotnēs pieejamo informāciju." "Atkļūdošanas datu kopīgošana" "Vai kopīgot detalizētus atkļūdošanas datus?" "%1$s vēlas augšupielādēt atkļūdošanas informāciju." diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml index 1207612c7..7a894bd4d 100644 --- a/res/values-mk/strings.xml +++ b/res/values-mk/strings.xml @@ -168,6 +168,11 @@ "Отвори" "Деинсталирај" "Исклучи присилно" + "Поставки" + "%s има целосен пристап до уредот" + "%s услуги за пристапност имаат целосен пристап до уредот" + "%s може да го гледа вашиот екран, дејствата и записите, да извршува дејства и да го контролира приказот." + "Овие услуги може да го гледаат вашиот екран, дејствата и записите, да извршуваат дејства и да го контролираат приказот." "Стандардни апликации" "Нема стандардни апликации" "Стандардно за работа" @@ -176,6 +181,7 @@ "Посебен пристап за апликации" "Нема посебен пристап за аплик." "Нема апликации" + "Апликација за помош" "Прелистувач" "Апликација Телефон" "Апликација за SMS" @@ -184,13 +190,13 @@ "Апликација за музика" "Апликација за галерија" "Телефонска апликација Car mode" - - + "Аплик. за пренасочување повици" "Аплик. за проверка на повици" "Повикај придружна апликација" - "Апликација за помош" "Апликација Car Projection" + "Не поддржува работен профил" "Забелешка: Ако го рестартирате уредот, а имате поставено заклучување на екранот, апликацијава нема да може да се стартува додека не го отклучите уредот." + "Помошникот ќе може да чита информации за апликациите што се користат во системот, вклучувајќи ги информациите што се видливи на екранот или до коишто може се пристапи во апликациите." "Споделете податоци за отстранување грешки" "Да се споделат податоци за отстранување грешки?" "%1$s сака да прикачи информации за отстранување грешки." diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml index 481d82a66..efd9a7219 100644 --- a/res/values-ml/strings.xml +++ b/res/values-ml/strings.xml @@ -168,6 +168,16 @@ "തുറക്കുക" "അൺഇൻസ്‌റ്റാൾ ചെയ്യുക" "നിർബന്ധിതമായി നിർത്തുക" + + + + + + + + + + "ഡിഫോൾട്ട് ആപ്പുകൾ" "ഡിഫോൾട്ട് ആപ്പുകൾ ഇല്ല" "ജോലി ആവശ്യങ്ങൾക്ക് ഡിഫോൾട്ട്" @@ -176,6 +186,7 @@ "പ്രത്യേക ആപ്പ് ആക്‌സസ്" "പ്രത്യേക ആപ്പ് ആക്‌സസില്ല" "ആപ്പുകൾ ലഭ്യമല്ല" + "സഹായ ആപ്പ്" "ബ്രൗസർ ആപ്പ്" "ഫോൺ ആപ്പ്" "SMS ആപ്പ്" @@ -184,13 +195,15 @@ "സംഗീത ആപ്പ്" "ഗാലറി ആപ്പ്" "കാർ മോഡ് ഫോൺ ആപ്പ്" - - + "കോൾ റീഡയറക്‌ട് ചെയ്യുന്ന ആപ്പ്" "കോൾ സ്‌ക്രീനിംഗ് ആപ്പ്" "കോൾ സഹകാരി ആപ്പ്" - "സഹായ ആപ്പ്" "കാർ പ്രൊജക്ഷൻ ആപ്പ്" + + "ശ്രദ്ധിക്കുക: നിങ്ങളുടെ ഉപകരണം റീസ്‌റ്റാർട്ട് ചെയ്‌ത്, സ്‌ക്രീൻ ലോക്ക് സജ്ജീകരിച്ചിട്ടുണ്ടെങ്കിൽ, നിങ്ങളുടെ ഉപകരണം അൺലോക്ക് ചെയ്യുന്നത് വരെ ഈ ആപ്പ് ആരംഭിക്കാനാവില്ല." + + "ഡീബഗ്ഗ് ചെയ്യൽ ഡാറ്റ പങ്കിടുക" "വിശദമായ ഡീബഗ്ഗ് ചെയ്യൽ വിവരങ്ങൾ പങ്കിടണോ?" "ഡീബഗ്ഗ് ചെയ്യൽ വിവരങ്ങൾ അപ്‌ലോഡ് ചെയ്യാൻ %1$s താൽപ്പര്യപ്പെടുന്നു." diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml index 1035c1242..73e2aab76 100644 --- a/res/values-mn/strings.xml +++ b/res/values-mn/strings.xml @@ -168,6 +168,11 @@ "Нээх" "Устгах" "Хүчээр зогсоох" + "Тохиргоо" + "%s таны төхөөрөмжид хандах бүрэн эрхтэй байна" + "Таны төхөөрөмжид %s хүртээмжийн үйлчилгээ хандах бүрэн эрхтэй байна" + "%s таны дэлгэц, үйлдэл, оролтыг харах, үйлдэл гүйцэтгэх болон дэлгэцийг хянах боломжтой." + "Эдгээр үйлчилгээ таны дэлгэц, үйлдэл, оролтыг харах, үйлдэл гүйцэтгэх болон дэлгэцийг хянах боломжтой." "Өгөгдмөл аппууд" "Өгөгдмөл аппууд алга" "Ажлын өгөгдмөл апп" @@ -176,6 +181,7 @@ "Аппын тусгай хандалт" "Аппын тусгай хандалт алга" "Апп алга" + "Туслах пп" "Хөтөч апп" "Гар утасны апп" "SMS апп" @@ -184,13 +190,13 @@ "Хөгжмийн апп" "Галерейны апп" "Машины горимын утасны апп" - - + "Дуудлагыг дахин чиглүүлэх апп" "Дуудлага шүүх апп" "Дуудлага дэмжигч апп" - "Туслах пп" "Машины үнэлгээний апп" + "Ажлын профайлыг дэмждэггүй" "Санамж: Хэрвээ та төхөөрөмжөө дахин эхлүүлж, дэлгэцийн түгжээ тохируулбал энэ апп таныг төхөөрөмжийнхөө түгжээг тайлах хүртэл эхлэх боломжгүй." + "Туслах таны дэлгэцэд харагддаг эсвэл аппуудаас хандах боломжтой мэдээлэл зэрэг таны системд ашигладаг аппуудын талаарх мэдээллийг унших боломжтой болно." "Алдаа засах өгөгдлийг хуваалцах" "Алдаа засах дэлгэрэнгүй өгөгдлийг хуваалцах уу?" "%1$s алдаа засах мэдээллийг байршуулах хүсэлтэй байна." diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml index e829fbcec..4f9422a16 100644 --- a/res/values-mr/strings.xml +++ b/res/values-mr/strings.xml @@ -168,6 +168,16 @@ "उघडा" "अनइंस्टॉल करा" "सक्तीने थांबवा" + + + + + + + + + + "डीफॉल्ट अ‍ॅप्स" "कोणतीही डीफॉल्‍ट अ‍ॅप्स नाहीत" "कार्यासाठी डीफॉल्ट" @@ -176,6 +186,7 @@ "विशेष अॅप अॅक्सेस" "कोणताही विशेष अॅप अॅक्सेस नाही" "कोणतीही अॅप्स नाहीत" + "साहाय्य अ‍ॅप" "ब्राउझर अ‍ॅप" "फोन अ‍ॅप" "एसएमएस अ‍ॅप" @@ -184,13 +195,15 @@ "म्युझिक अ‍ॅप" "गॅलरी अ‍ॅप" "कार मोड फोन अ‍ॅप" - - + "कॉल रीडिरेक्‍ट करणारे अ‍ॅप" "स्क्रीनिंग अ‍ॅपला कॉल करा" "सहयोगी अ‍ॅपला कॉल करा" - "साहाय्य अ‍ॅप" "कार प्रोजेक्शन अ‍ॅप" + + "टीप: तुम्ही तुमचे डिव्हाइस रीस्टार्ट केल्यास आणि स्क्रीन लॉक सेट केले असल्यास, तुम्ही तुमचे डिव्हाइस अनलॉक करेपर्यंत हे अ‍ॅप सुरू होऊ शकत नाही." + + "डीबगिंग डेटा शेअर करा" "तपशीलवार डीबगिंग डेटा शेअर करायचा?" "%1$s ला डीबगिंग माहिती अपलोड करायला आवडेल." diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml index 9fde4f99e..78562f843 100644 --- a/res/values-ms/strings.xml +++ b/res/values-ms/strings.xml @@ -168,6 +168,16 @@ "Buka" "Nyahpasang" "Henti paksa" + + + + + + + + + + "Apl lalai" "Tiada apl lalai" "Lalai untuk kerja" @@ -176,6 +186,7 @@ "Akses apl khas" "Tiada akses apl khas" "Tiada apl" + "Apl Bantu" "Apl penyemak imbas" "Apl Telefon" "Apl SMS" @@ -184,13 +195,15 @@ "Apl Muzik" "Apl Galeri" "Apl telefon mod kereta" - - + "Apl pengubahhalaan panggilan" "Apl penyaringan panggilan" "Apl rakan panggilan" - "Apl Bantu" "Apl Unjuran Kereta" + + "Nota: Jika anda memulakan semula peranti dan telah menetapkan kunci skrin, apl ini tidak boleh dimulakan sehingga anda membuka kunci peranti anda." + + "Kongsi Data Penyahpepijatan" "Kongsi data penyahpepijatan secara terperinci?" "%1$s mahu memuat naik maklumat penyahpepijatan." diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml index b91b08cd1..ac5252494 100644 --- a/res/values-my/strings.xml +++ b/res/values-my/strings.xml @@ -168,6 +168,11 @@ "ဖွင့်ရန်" "ဖြုတ်ရန်" "ချက်ချင်း ရပ်ရန်" + "ဆက်တင်များ" + "%s သည် သင့်ကိရိယာအား အပြည့်အဝ အသုံးပြုခွင့်ရှိသည်" + "အများသုံးစွဲနိုင်မှုဆိုင်ရာ ဝန်ဆောင်မှု %s ခုသည် သင့်ကိရိယာအား အပြည့်အဝ အသုံးပြုခွင့်ရှိသည်" + "%s သည် သင်၏ မျက်နှာပြင်၊ လုပ်ဆောင်ချက်များ၊ ထည့်သွင်းမှုများကို ကြည့်နိုင်ပြီး လုပ်ဆောင်ချက်များကို ဆောင်ရွက်နိုင်သည့်အပြင် မျက်နှာပြင်သမှုကိုလည်း ထိန်းချုပ်နိုင်သည်။" + "ဤဝန်ဆောင်မှုများသည် သင်၏ မျက်နှာပြင်၊ လုပ်ဆောင်ချက်များ၊ ထည့်သွင်းမှုများကို ကြည့်နိုင်ပြီး လုပ်ဆောင်ချက်များကို ဆောင်ရွက်နိုင်သည့်အပြင် မျက်နှာပြင်သမှုကိုလည်း ထိန်းချုပ်နိုင်သည်။" "မူရင်း အက်ပ်များ" "မူရင်းအက်ပ်မရှိပါ" "အလုပ်အတွက် မူရင်း" @@ -176,6 +181,7 @@ "အထူးအက်ပ်များ သုံးခွင့်ရှိသည်" "အထူးအက်ပ်များ သုံးခွင့်မရှိပါ" "အက်ပ် မရှိပါ" + "အကူအညီ အက်ပ်" "ဘရောင်ဇာ အက်ပ်" "ဖုန်းအက်ပ်" "SMS အက်ပ်" @@ -184,13 +190,13 @@ "တေးဂီတ အက်ပ်" "ပုံပြခန်းအက်ပ်" "ကားမုဒ်ဖုန်းအက်ပ်" - - + "ခေါ်ဆိုမှု တစ်ဆင့်ညွှန်အက်ပ်" "ခေါ်ဆိုမှု စစ်ဆေးခြင်းအက်ပ်" "ခေါ်ဆိုမှု အကူအညီအက်ပ်" - "အကူအညီ အက်ပ်" "ကားပုံစံပြသည့် အက်ပ်" + "အလုပ်ပရိုဖိုင်ကို မပံ့ပိုးပါ" "မှတ်ချက်- သင်၏စက်ပစ္စည်းကို ပြန်လည်စတင်ပြီး မျက်နှာပြင်လော့ခ်ချထားလျှင် ၎င်းကို လော့ခ်မဖွင့်မချင်း ဤအက်ပ်ကို အသုံးပြု၍မရပါ။" + "Assistant သည် သင်၏ မျက်နှာပြင်ပေါ်တွင် မြင်ရသည့် သို့မဟုတ် အက်ပ်များအတွင်း ရယူအသုံးပြုနိုင်သည့် အချက်အလက်များအပါအဝင် သင်၏ စနစ်ထဲတွင် အသုံးပြုနေသည့် အက်ပ်များနှင့် ပတ်သက်သည့် အချက်အလက်များကို ဖတ်ရှုနိုင်မည်ဖြစ်သည်။" "အမှားရှာပြင်သည့် ဒေတာ မျှဝေခြင်း" "အမှားရှာပြင်သည့် ဒေတာ အသေးစိတ်ကို မျှဝေလိုသလား။" "%1$s က အမှားရှာပြင်သည့် အချက်အလက်ကို အပ်လုဒ်လုပ်လိုသည်။" diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml index a0f2982c6..30ee97a22 100644 --- a/res/values-nb/strings.xml +++ b/res/values-nb/strings.xml @@ -168,6 +168,11 @@ "Åpne" "Avinstaller" "Tving til å avslutte" + "Innstillinger" + "%s har full tilgang til enheten din" + "%s tilgjengelighetstjenester har full tilgang til enheten din" + "%s kan se skjermen, handlinger og inndata, utføre handlinger og kontrollere skjermen." + "Disse tjenestene kan se skjermen, handlinger og inndata, utføre handlinger og kontrollere skjermen." "Standardapper" "Ingen standardapper" "Jobbstandard" @@ -176,6 +181,7 @@ "Spesiell apptilgang" "Ingen spesiell apptilgang" "Ingen apper" + "Assistentapp" "Nettleserapp" "Telefon-app" "SMS-app" @@ -184,13 +190,13 @@ "Musikk-appen" "Galleri-appen" "Telefonapp for bilmodus" - - + "App for viderekobling av anrop" "App for anropsutvelgelse" "Følgeapp for ringing" - "Assistentapp" "App for speiling i bilen" + "Støtter ikke jobbprofiler" "Merk: Hvis du starter enheten din på nytt og har en skjermlås angitt, kan ikke denne appen starte før du låser opp enheten." + "Assistenten kan lese informasjon om appene du bruker i systemet ditt, inkludert informasjon som er synlig på skjermen eller tilgjengelig i appene." "Del feilsøkingsdata" "Vil du dele detaljerte feilsøkingsdata?" "%1$s vil laste opp feilsøkingsinformasjon." diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml index bb93a6465..7a42d8339 100644 --- a/res/values-ne/strings.xml +++ b/res/values-ne/strings.xml @@ -168,6 +168,11 @@ "खोल्नुहोस्" "स्थापना रद्द गर्नुहोस्" "जबरजस्ती रोक्नुहोस्" + "सेटिङहरू" + "%s ले तपाईंको यन्त्रमाथि पूर्ण रूपमा पहुँच राख्न सक्छ" + "पहुँचसम्बन्धी %s सेवाहरूले तपाईंको यन्त्रमाथि पूर्ण रूपमा पहुँच राख्न सक्छन्" + "%s ले तपाईंको स्क्रिन, कारबाही र इनपुट हेर्न, कारबाहीहरू गर्न र डिस्प्ले नियन्त्रण गर्न सक्छ।" + "यी सेवाहरूले तपाईंको स्क्रिन, कारबाही र इनपुट हेर्न, कारबाहीहरू गर्न र डिस्प्ले नियन्त्रण गर्न सक्छन्।" "पूर्वनिर्धारित अनुप्रयोगहरू" "कुनै पनि पूर्वनिर्धारित अनुप्रयोग छैन" "कार्यका लागि पूर्वनिर्धारित" @@ -176,6 +181,7 @@ "अनुप्रयोगसम्बन्धी विशेष पहुँच" "एपसम्बन्धी कुनै विशेष पहुँच छैन" "कुनै पनि अनुप्रयोग छैन" + "सहायक अनुप्रयोग" "ब्राउजर अनुप्रयोग" "फोन अनुप्रयोग" "SMS अनुप्रयोग" @@ -184,13 +190,13 @@ "सङ्गीत अनुप्रयोग" "ग्यालरी अनुप्रयोग" "कार मोड नामक फोन अनुप्रयोग" - - + "कल रिडिरेक्ट गर्ने अनुप्रयोग" "कललाई स्क्रिनमा देखाउने अनुप्रयोग" "सहयोगी अनुप्रयोगलाई कल गर्नु…" - "सहायक अनुप्रयोग" "कारको प्रोजेक्सनको अनुप्रयोग" + "कार्य प्रोफाइल समर्थन गर्दैन" "टिपोट: तपाईंले आफ्नो यन्त्र पुनः सुरु गर्नुभयो र त्यसमा स्क्रिन लक सेट गरिएको छ भने तपाईंले आफ्नो यन्त्र अनलक नगरेसम्म यो अनुप्रयोग सुरु हुन सक्दैन।" + "सहायकले तपाईंको स्क्रिनमा देखिने वा अनुप्रयोगभित्रबाट पहुँच राख्न सकिने जानकारीलगायत तपाईंको प्रणालीमा प्रयोगमा रहेका अनुप्रयोगसम्बन्धी जानकारी पढ्न सक्ने छ।" "डिबग प्रक्रियासम्बन्धी डेटा आदान प्रदान गर्नुहोस्" "डिबग प्रक्रियाको विस्तृत डेटा आदान प्रदान गर्ने?" "%1$s डिबग प्रक्रियासम्बन्धी जानकारी अपलोड गर्न चाहन्छ।" diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml index 03b8d4d87..5e2031031 100644 --- a/res/values-nl/strings.xml +++ b/res/values-nl/strings.xml @@ -168,6 +168,11 @@ "Openen" "Verwijderen" "Gedwongen stoppen" + "Instellingen" + "%s heeft volledige toegang tot je apparaat" + "%s toegankelijkheidsservices hebben volledige toegang tot je apparaat" + "%s kan je scherm, acties en invoer bekijken, acties uitvoeren en het display beheren." + "Deze services kunnen je scherm, acties en invoer bekijken, acties uitvoeren en het display beheren." "Standaard-apps" "Geen standaard-apps" "Standaard voor werk" @@ -176,6 +181,7 @@ "Speciale app-toegang" "Geen speciale app-toegang" "Geen apps" + "App voor assistentie" "Browser-app" "Telefoon-app" "Sms-app" @@ -184,13 +190,13 @@ "Muziek-app" "Galerij-app" "Telefoon-app voor automodus" - - + "App voor gesprekdoorschakeling" "App voor gesprekken screenen" "Bijbehorende app voor bellen" - "App voor assistentie" "Autoprojectie-app" + "Ondersteunt geen werkprofielen" "Opmerking: Als je het apparaat opnieuw opstart en een schermvergrendeling hebt ingesteld, kan deze app pas worden gestart nadat je het apparaat hebt ontgrendeld." + "De Assistent kan informatie over de gebruikte apps in je systeem lezen, waaronder informatie die zichtbaar is op je scherm of toegankelijk is in de apps." "Foutopsporingsgegevens delen" "Gedetailleerde foutopsporingsgegevens delen?" "%1$s wil foutopsporingsinformatie uploaden." diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml index e22a1c7bb..0a5cf7182 100644 --- a/res/values-or/strings.xml +++ b/res/values-or/strings.xml @@ -168,6 +168,16 @@ "ଖୋଲନ୍ତୁ" "ଅନ୍‍ଇନ୍‍ଷ୍ଟଲ୍‌ କରନ୍ତୁ" "ଜବରଦସ୍ତି ବନ୍ଦ କରନ୍ତୁ" + + + + + + + + + + "ଡିଫଲ୍ଟ ଆପ୍ସ" "କୌଣସି ଡିଫଲ୍ଟ ଆପ୍ସ ନାହିଁ" "କାର୍ଯ୍ୟ ପାଇଁ ଡିଫଲ୍ଟ ଅଛି" @@ -176,6 +186,7 @@ "ଆପ୍‌ ଆକ୍ସେସ୍‌ ବାଛନ୍ତୁ" "କୌଣସି ସ୍ଵତନ୍ତ୍ର ଆପ୍‍ ଆକ୍ସେସ୍‍ ନାହିଁ" "କୌଣସି ଆପ୍‌ ନାହିଁ" + "ସହାୟକ ଆପ୍‌" "ବ୍ରାଉଜର୍‌ ଆପ୍‌" "ଫୋନ୍‌ ଆପ୍‌" "SMS ଆପ୍‌" @@ -184,13 +195,15 @@ "Music ଆପ୍‍" "Gallery ଆପ୍‍" "କାର୍ ମୋଡ୍ ଫୋନ୍ ଆପ୍" - - + "କଲ୍ ପୁନଃନିର୍ଦ୍ଦେଶିତ କରୁଥିବା ଆପ୍" "କଲ୍ ସ୍କ୍ରିନିଂ ଆପ୍" "ସହଯୋଗୀ ଆପ୍‌କୁ କଲ୍ କରନ୍ତୁ" - "ସହାୟକ ଆପ୍‌" "କାର୍ ପ୍ରୋଜେକ୍ସନ୍ ଆପ୍" + + "ଟିପ୍ପଣୀ: ଯଦି ଆପଣ ଆପଣଙ୍କ ଡିଭାଇସ୍ ରିଷ୍ଟାର୍ଟ କରିବେ ଏବଂ ଏକ ସ୍କ୍ରିନ୍ ଲକ୍ ସେଟ୍ ହେବ, ଆପଣଙ୍କ ଡିଭାଇସ୍ ଅନ୍‌ଲକ୍ ନହେବା ପର୍ଯ୍ୟନ୍ତ ଏହି ଆପ୍ ଆରମ୍ଭ ହୋଇପାରିବ ନାହିଁ।" + + "ଡିବଗିଂ ଡାଟା ସେୟାର୍ କରନ୍ତୁ" "ବିସ୍ତୃତ ଡିବଗିଂ ଡାଟା ସେୟାର୍ କରିବେ?" "%1$s ଡିବଗିଂ ସୂଚନା ଅପ୍‌ଲୋଡ୍ କରିବାକୁ ଚାହାନ୍ତି।" diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml index 328a6ddd7..e69084fa5 100644 --- a/res/values-pa/strings.xml +++ b/res/values-pa/strings.xml @@ -168,6 +168,16 @@ "ਖੋਲ੍ਹੋ" "ਅਣਸਥਾਪਤ ਕਰੋ" "ਜ਼ਬਰਦਸਤੀ ਬੰਦ ਕਰੋ" + + + + + + + + + + "ਪੂਰਵ-ਨਿਰਧਾਰਤ ਐਪਾਂ" "ਕੋਈ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਐਪਾਂ ਨਹੀਂ" "ਕੰਮ ਲਈ ਪੂਰਵ-ਨਿਰਧਾਰਤ" @@ -176,6 +186,7 @@ "ਵਿਸ਼ੇਸ਼ ਐਪ ਪਹੁੰਚ" "ਕੋਈ ਵਿਸ਼ੇਸ਼ ਐਪ ਪਹੁੰਚ ਨਹੀਂ" "ਕੋਈ ਐਪਾਂ ਨਹੀਂ" + "ਸਹਾਇਕ ਐਪ" "ਬ੍ਰਾਊਜ਼ਰ ਐਪ" "ਫ਼ੋਨ ਐਪ" "SMS ਐਪ" @@ -184,13 +195,15 @@ "ਸੰਗੀਤ ਐਪ" "ਗੈਲਰੀ ਐਪ" "ਕਾਰ ਮੋਡ ਫ਼ੋਨ ਐਪ" - - + "ਕਾਲ ਨੂੰ ਰੀਡਾਇਰੈਕਟ ਕਰਨ ਵਾਲੀ ਐਪ" "ਕਾਲ ਸਕ੍ਰੀਨਿੰਗ ਐਪ" "ਕਾਲ ਸੰਬੰਧੀ ਐਪ" - "ਸਹਾਇਕ ਐਪ" "ਕਾਰ ਦੀ ਯੋਜਨਾਬੰਦੀ ਐਪ" + + "ਨੋਟ-ਕਥਨ: ਜੇਕਰ ਤੁਸੀਂ ਆਪਣੇ ਡੀਵਾਈਸ ਨੂੰ ਮੁੜ-ਸ਼ੁਰੂ ਕਰਦੇ ਹੋ ਅਤੇ ਸਕ੍ਰੀਨ ਲਾਕ ਸੈੱਟ ਕੀਤਾ ਹੋਇਆ ਹੈ, ਤਾਂ ਇਹ ਐਪਾ ਤੁਹਾਡੇ ਵੱਲੋਂ ਆਪਣੇ ਡੀਵਾਈਸ ਨੂੰ ਅਣਲਾਕ ਕੀਤੇ ਨਾ ਹੋਣ ਤੱਕ ਸ਼ੁਰੂ ਨਹੀਂ ਹੋਵੇਗੀ।" + + "ਡੀਬੱਗਿੰਗ ਡਾਟਾ ਸਾਂਝਾ ਕਰੋ" "ਕੀ ਵੇਰਵੇ ਸਮੇਤ ਡੀਬੱਗਿੰਗ ਡਾਟਾ ਸਾਂਝਾ ਕਰਨਾ ਹੈ?" "%1$s ਡੀਬੱਗਿੰਗ ਜਾਣਕਾਰੀ ਨੂੰ ਅੱਪਲੋਡ ਕਰਨਾ ਚਾਹੁੰਦੀ ਹੈ।" diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml index 931d69b0e..f80e7a741 100644 --- a/res/values-pl/strings.xml +++ b/res/values-pl/strings.xml @@ -178,6 +178,11 @@ "Otwórz" "Odinstaluj" "Wymuś zatrzymanie" + "Ustawienia" + "Usługa %s ma pełny dostęp do urządzenia" + "Usługi ułatwień dostępu (%s) mają pełny dostęp do urządzenia" + "Usługa %s może wyświetlać ekran, działania i wprowadzane dane, wykonywać działania i zarządzać wyświetlaczem." + "Te usługi mogą wyświetlać ekran, działania i wprowadzane dane, wykonywać działania i zarządzać wyświetlaczem." "Aplikacje domyślne" "Brak domyślnych aplikacji" "Domyślne do pracy" @@ -186,6 +191,7 @@ "Specjalny dostęp do aplikacji" "Brak specjalnego dostępu do aplikacji" "Brak aplikacji" + "Aplikacja asystująca" "Przeglądarka" "Telefon" "Aplikacja do SMS-ów" @@ -194,13 +200,13 @@ "Aplikacja Muzyka" "Aplikacja Galeria" "Aplikacja na telefon, tryb samochodowy" - - + "Aplikacja przekierowująca połączenia" "Aplikacja do filtrowania połączeń" "Aplikacja towarzysząca połączeniom" - "Aplikacja asystująca" "Aplikacja do wyświetlania treści w samochodzie" + "Nie obsługuje profilu do pracy" "Uwaga: Po ponownym uruchomieniu urządzenia z ustawioną blokadą ekranu ta aplikacja będzie mogła uruchomić się dopiero wtedy, gdy odblokujesz urządzenie." + "Asystent będzie mógł odczytywać informacje o aplikacjach używanych w systemie. Obejmuje to też informacje widoczne na ekranie i dostępne w aplikacjach." "Udostępnianie danych debugowania" "Udostępnić szczegółowe dane debugowania?" "%1$s chce przesłać informacje debugowania." diff --git a/res/values-pt-rBR/strings.xml b/res/values-pt-rBR/strings.xml index ff38f6f47..e97b6a9e3 100644 --- a/res/values-pt-rBR/strings.xml +++ b/res/values-pt-rBR/strings.xml @@ -168,6 +168,11 @@ "Abrir" "Desinstalar" "Forçar fechamento" + "Configurações" + "O serviço %s tem acesso total ao seu dispositivo" + "%s serviços de acessibilidade com acesso total ao seu dispositivo" + "O serviço %s pode ver sua tela, ações e entradas, além de realizar ações e controlar a tela." + "Esses serviços podem ver sua tela, ações e entradas, além de realizar ações e controlar a tela." "Apps padrão" "Nenhum app padrão" "Padrão para trabalho" @@ -176,6 +181,7 @@ "Acesso especial ao app" "Nenhum acesso especial ao app" "Nenhum app" + "App assistivo" "App de navegação" "App Telefone" "App de SMS" @@ -184,13 +190,13 @@ "App de música" "App de galeria" "App Telefone no modo carro" - - + "App p/ redirecionar chamadas" "App identificador de chamadas" "App complementar de chamadas" - "App assistivo" "App de projeção do carro" + "Não é compatível com perfil de trabalho" "Observação: se você reiniciar o dispositivo e tiver um bloqueio de tela definido, não será possível iniciar este app até que você desbloqueie o dispositivo." + "O assistente lerá informações sobre apps em uso no seu sistema, incluindo informações visíveis na tela ou as que podem ser acessadas nos apps." "Compartilhar dados de depuração" "Compartilhar dados detalhados de depuração?" "Solicitação do %1$s para upload de informações de depuração." diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml index 7abf219e6..99406495d 100644 --- a/res/values-pt-rPT/strings.xml +++ b/res/values-pt-rPT/strings.xml @@ -168,6 +168,11 @@ "Abrir" "Desinstalar" "Forçar paragem" + "Definições" + "O serviço %s tem acesso total ao seu dispositivo" + "%s serviços de acessibilidade têm acesso total ao seu dispositivo" + "O serviço %s pode ver o seu ecrã, as ações e as entradas, efetuar ações e controlar o ecrã." + "Estes serviços podem ver o ecrã, as ações e as entradas, efetuar ações e controlar o ecrã." "Aplicações predefinidas" "Sem aplicações predefinidas" "Predefinição para o trabalho" @@ -176,6 +181,7 @@ "Acesso especial a aplicações" "Sem acesso especial a aplic." "Sem aplicações" + "Aplicação de assistência" "Aplicação de navegador" "Aplicação Telefone" "Aplicação de SMS" @@ -184,13 +190,13 @@ "Aplicação de música" "Aplicação de galeria" "Aplic. Telefone modo automóvel" - - + "Aplic. de redirec. de chamadas" "Aplic. de filtro de chamadas" "Aplic. associada de chamadas" - "Aplicação de assistência" "Aplicação Car Projection" + "Não suporta o perfil de trabalho." "Nota: se reiniciar o dispositivo e tiver um bloqueio de ecrã definido, só é possível iniciar esta aplicação quando o dispositivo for desbloqueado." + "O assistente pode ler informações sobre aplicações em utilização no seu sistema, incluindo informações visíveis no ecrã ou acessíveis nas aplicações." "Partilhar dados de depuração" "Pretende partilhar dados de depuração detalhados?" "A aplicação %1$s pretende carregar informações de depuração." diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml index ff38f6f47..e97b6a9e3 100644 --- a/res/values-pt/strings.xml +++ b/res/values-pt/strings.xml @@ -168,6 +168,11 @@ "Abrir" "Desinstalar" "Forçar fechamento" + "Configurações" + "O serviço %s tem acesso total ao seu dispositivo" + "%s serviços de acessibilidade com acesso total ao seu dispositivo" + "O serviço %s pode ver sua tela, ações e entradas, além de realizar ações e controlar a tela." + "Esses serviços podem ver sua tela, ações e entradas, além de realizar ações e controlar a tela." "Apps padrão" "Nenhum app padrão" "Padrão para trabalho" @@ -176,6 +181,7 @@ "Acesso especial ao app" "Nenhum acesso especial ao app" "Nenhum app" + "App assistivo" "App de navegação" "App Telefone" "App de SMS" @@ -184,13 +190,13 @@ "App de música" "App de galeria" "App Telefone no modo carro" - - + "App p/ redirecionar chamadas" "App identificador de chamadas" "App complementar de chamadas" - "App assistivo" "App de projeção do carro" + "Não é compatível com perfil de trabalho" "Observação: se você reiniciar o dispositivo e tiver um bloqueio de tela definido, não será possível iniciar este app até que você desbloqueie o dispositivo." + "O assistente lerá informações sobre apps em uso no seu sistema, incluindo informações visíveis na tela ou as que podem ser acessadas nos apps." "Compartilhar dados de depuração" "Compartilhar dados detalhados de depuração?" "Solicitação do %1$s para upload de informações de depuração." diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml index b31a8047d..9961e90be 100644 --- a/res/values-ro/strings.xml +++ b/res/values-ro/strings.xml @@ -173,6 +173,11 @@ "Deschideți" "Dezinstalați" "Opriți forțat" + "Setări" + "%s are acces deplin la dispozitivul dvs." + "%s servicii de accesibilitate au acces deplin la dispozitivul dvs." + "%s poate să vă vadă ecranul, acțiunile și textul pe care îl introduceți, să efectueze acțiuni și să controleze afișajul." + "Aceste servicii pot să vă vadă ecranul, acțiunile și textul pe care îl introduceți, să efectueze acțiuni și să controleze afișajul." "Aplicații prestabilite" "Nicio aplicație prestabilită." "Prestabilite pentru serviciu" @@ -181,6 +186,7 @@ "Acces special pentru aplicații" "Niciun acces special pentru aplicații" "Nicio aplicație" + "Aplicație asistent" "Aplicația Browser" "Aplicația Telefon" "Aplicația SMS" @@ -189,13 +195,13 @@ "Aplicația Muzică" "Aplicația Galerie" "Aplicația pentru telefon în modul Mașină" - - + "Aplicația de redirecționare a apelurilor" "Aplicația de filtrare a apelurilor" "Aplicație partener de apelare" - "Aplicație asistent" "Aplicația pentru proiecția mașinii" + "Nu acceptă profilul de serviciu" "Notă: dacă reporniți telefonul și aveți activată blocarea ecranului, această aplicație nu poate porni până nu deblocați telefonul." + "Aplicația asistent va putea să citească informații despre aplicațiile în uz de pe sistem, inclusiv informațiile vizibile pe ecran sau accesibile în aplicații." "Trimiteți datele despre remedierea erorilor" "Trimiteți datele detaliate despre remedierea erorilor?" "%1$s dorește să încarce informațiile despre remedierea erorilor." diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index 71cc4048d..60210130c 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -178,6 +178,16 @@ "Открыть" "Удалить" "Остановить принудительно" + + + + + + + + + + "Приложения по умолчанию" "Нет приложений по умолчанию" "Стандартные для работы" @@ -186,6 +196,7 @@ "Спец. доступ для приложений" "Специальный доступ не настроен" "Нет приложений" + "Помощник" "Браузер" "Приложение для звонков" "Приложение для SMS" @@ -194,13 +205,15 @@ "Музыка" "Галерея" "Приложение для звонков во время вождения" - - + "Перенаправление вызовов" "Приложение для управления входящими вызовами" "Сопутствующее приложение для звонков" - "Помощник" "Трансляция на экран автомобиля" + + "Примечание. Если у вас установлена блокировка экрана, после перезагрузки вам потребуется разблокировать устройство, чтобы запустить приложение." + + "Отправка данных об отладке" "Отправка детализированных данных об отладке" "Приложение \"%1$s\" запрашивает разрешение на загрузку данных об отладке." diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml index e3adf4b78..03585ea9a 100644 --- a/res/values-si/strings.xml +++ b/res/values-si/strings.xml @@ -168,6 +168,11 @@ "විවෘත කරන්න" "අස්ථාපනය" "බලෙන් නවතන්න" + "සැකසීම්" + "%s හට ඔබේ උපාංගය වෙත පූර්ණ ප්‍රවේශය තිබේ" + "%s ප්‍රවේශ්‍යතා සේවාවලට ඔබේ උපාංගය වෙත පූර්ණ ප්‍රවේශය තිබේ" + "%s හට ඔබේ තිරය, ක්‍රියා, සහ ආදාන බැලීමට, කාර්ය ඉටු කිරීමට, සහ සංදර්ශකය පාලන කිරීමට හැකි ය." + "මෙම සේවාවලට ඔබේ තිරය, ක්‍රියා, සහ ආදාන බැලීමට, කාර්ය ඉටු කිරීමට, සහ සංදර්ශකය පාලන කිරීමට හැකි ය." "පෙරනිමි යෙදුම්" "පෙරනිමි යෙදුම් නැත" "වැඩ සඳහා පෙරනිමි" @@ -176,6 +181,7 @@ "විශේෂ යෙදුම් ප්‍රවේශය" "විශේෂිත යෙදුම් ප්‍රවේශයක් නැත" "යෙදුම් නැත" + "සහය යෙදුම" "බ්‍රවුසර යෙදුම" "දුරකථන යෙදුම" "කෙටි පණිවුඩ යෙදුම" @@ -184,13 +190,13 @@ "සංගීත යෙදුම" "Gallery යෙදුම" "රිය ප්‍රකාර දුරකථන යෙදුම" - - + "ඇමතුම් ප්‍රතියොමු කරන යෙදුම" "ඇමතුම් පරීක්ෂා කිරීමේ යෙදුම" "ඇමතුම් සහායක යෙදුම" - "සහය යෙදුම" "මෝටර් රථ ප්‍රක්ෂේපන යෙදුම" + "වැඩ පැතිකඩට සහය නොදක්වයි" "සටහන: ඔබ ඔබේ උපාංගය යළි අරඹන්නේ නම් සහ තිර අඟුලක් සකසා තිබේ නම්, ඔබ ඔබේ උපාංගය අඟුලු අරින තෙක් මෙම යෙදුම ආරම්භ විය නොහැක." + "සහකරුට ඔබේ තිරය මත දෘශ්‍යමාන වන හෝ යෙදුම් තුළ ප්‍රවේශ විය හැකි තොරතුරු ඇතුළුව, ඔබේ පද්ධතිය මත භාවිතයේ ඇති යෙදුම් ගැන කියවීමට හැකි වෙයි." "නිදොසීම් දත්ත බෙදා ගන්න" "විස්තරාත්මක නිදොසීම් දත්ත බෙදා ගන්න ද?" "%1$s නිදොසීම් තොරතුරු උඩුගත කිරීමට කැමතිය." diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml index 270926d16..e64f1380d 100644 --- a/res/values-sk/strings.xml +++ b/res/values-sk/strings.xml @@ -178,6 +178,11 @@ "Otvoriť" "Odinštalovať" "Vynútiť zastavenie" + "Nastavenia" + "%s má úplný prístup do vášho zariadenia" + "Služby dostupnosti s úplným prístupom do vášho zariadenia: %s" + "%s si môže zobraziť vašu obrazovku, akcie a vstupy, vykonávať akcie a ovládať zobrazenie." + "Tieto služby si môžu zobraziť vašu obrazovku, akcie a vstupy, vykonávať akcie a ovládať zobrazenie." "Predvolené aplikácie" "Žiadne predvolené aplikácie" "Predvolené na prácu" @@ -186,6 +191,7 @@ "Špeciálny prístup aplikácií" "Žiadny špeciálny prístup aplikácií" "Žiadne aplikácie" + "Asistenčná aplikácia" "Prehliadač" "Aplikácia Telefón" "Aplikácia pre SMS a MMS" @@ -194,13 +200,13 @@ "Aplikácia Hudba" "Aplikácia Galéria" "Aplikácia režimu v aute pre telefóny" - - + "Aplikácia na presmer. hovorov" "Aplikácia na filtrovanie hovorov" "Sprievodná aplikácia na hovory" - "Asistenčná aplikácia" "Aplikácia na projekciu v aute" + "Nepodporuje pracovný profil" "Poznámka: Ak reštartujete zariadenie a máte nastavenú zámku obrazovky, táto aplikácia sa spustí až po odomknutí zariadenia." + "Pomocník bude môcť čítať informácie o aplikáciách používaných vo vašom systéme vrátane údajov viditeľných na obrazovke alebo prístupných v aplikáciách." "Zdieľanie údajov o ladení" "Chcete zdieľať podrobné údaje o ladení?" "%1$s chce nahrať informácie o ladení." diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml index 774f92346..ad17c800b 100644 --- a/res/values-sl/strings.xml +++ b/res/values-sl/strings.xml @@ -178,6 +178,11 @@ "Odpri" "Odmesti" "Prisilno ustavi" + "Nastavitve" + "Storitev %s ima poln dostop do naprave" + "Poln dostop do naprave ima toliko storitev za ljudi s posebnimi potrebami: %s" + "Storitev %s si lahko ogleduje zaslon, dejanja in vnose, izvaja dejanja in upravlja prikaz." + "Te storitve si lahko ogledujejo zaslon, dejanja in vnose, izvajajo dejanja in upravljajo prikaz." "Privzete aplikacije" "Ni privzetih aplikacij" "Privzeto za delo" @@ -186,6 +191,7 @@ "Posebni dostop za aplikacije" "Ni posebnega dostopa za aplik." "Ni aplikacij" + "Aplikacija za pomoč" "Brskalnik" "Aplikacija Telefon" "Aplikacija za SMS-je" @@ -194,13 +200,13 @@ "Aplikacija Glasba" "Aplikacija Galerija" "Apl. Telefon v načinu za avto." - - + "Aplikacija za preusm. klicev" "Aplikacija za pregled klicev" "Spremljevalna apl. za klicanje" - "Aplikacija za pomoč" "Apl. za projiciranje v avtu" + "Ne podpira delovnega profila" "Opomba: Po vnovičnem zagonu naprave z nastavljenim zaklepanjem zaslona se ta aplikacija ne more zagnati, dokler ne odklenete naprave." + "Pomočnik bo lahko bral podatke o aplikacijah, ki se uporabljajo v vašem sistemu, vključno s podatki, ki so vidni na zaslonu ali do katerih je mogoče dostopati v aplikacijah." "Pošiljanje podatkov za odpravljanje napak" "Želite poslati podrobne podatke za odprav. napak?" "Aplikacija %1$s želi naložiti podatke za odpravljanje napak." diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml index 6f9b1a545..914d01667 100644 --- a/res/values-sq/strings.xml +++ b/res/values-sq/strings.xml @@ -168,6 +168,11 @@ "Hap" "Çinstalo" "Ndalo me forcë" + "Cilësimet" + "%s ka qasje të plotë në pajisjen tënde" + "%s shërbime qasshmërie kanë qasje të plotë në pajisjen tënde" + "%s mund të shikojë ekranin tënd, veprimet dhe hyrjet, mund të kryejë veprime dhe kontrollojë ekranin." + "Këto shërbime mund të shikojnë ekranin tënd, veprimet dhe hyrjet, mund të kryejnë veprime dhe kontrollojë ekranin." "Aplikacionet e parazgjedhura" "Asnjë aplikacion i parazgjedhur" "Të parazgjedhura për punën" @@ -176,6 +181,7 @@ "Qasje e veçantë aplikacioni" "Jo qasje e veçantë aplikacioni" "Nuk ka aplikacione" + "Aplikacioni i asistentit" "Aplikacioni për shfletim" "Aplikacioni \"Telefoni\"" "Aplikacioni për SMS" @@ -184,13 +190,13 @@ "Aplikacioni i muzikës" "Aplikacioni i galerisë" "Apl. i modalitetit \"në makinë\"" - - + "Aplikacioni i ridrejtimit të telefonatave" "Apl. i filtrimit të telefonatave" "Apl. shoqërues i telefonatave" - "Aplikacioni i asistentit" "Aplikacioni i \"Projektimit të makinës\"" + "Profili i punës nuk mbështetet" "Shënim: Nëse e rinis pajisjen dhe ke caktuar një kyçje të ekranit, ky aplikacion nuk mund të niset derisa ta shkyçësh pajisjen." + "Asistenti do të jetë në gjendje të lexojë informacion rreth aplikacioneve në përdorim në sistemin tënd, duke përfshirë informacionin e dukshëm në ekran ose të qasshëm brenda aplikacioneve." "Ndaj të dhënat e korrigjimit" "Të ndahen të dhënat e detajuara të korrigjimit?" "%1$s dëshiron të ngarkojë informacionin e korrigjimit." diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml index 2c89bfbe2..30dddb4c1 100644 --- a/res/values-sr/strings.xml +++ b/res/values-sr/strings.xml @@ -173,6 +173,11 @@ "Отвори" "Деинсталирај" "Принудно заустави" + "Подешавања" + "%s има потпун приступ уређају" + "Услуге приступачности (%s) имају потпун приступ уређају" + "%s може да прегледа садржај екрана, радње и уносе, обавља радње и управља екраном." + "Ове услуге могу да прегледају садржај екрана, радње и уносе, обављају радње и управљају екраном." "Подразумеване апликације" "Нема подразумеване апликације." "Подразумевана за посао" @@ -181,6 +186,7 @@ "Приступ за спец. апликацију" "Нема приступа за спец. апл." "Нема апликација" + "Апликација за помоћ" "Апликација прегледача" "Апликација Телефон" "Апликација за SMS" @@ -189,13 +195,13 @@ "Апликација Музика" "Апликација Галерија" "Апликација за телефон са режимом рада у аутомобилу" - - + "Апликација преусмерава позиве" "Аплик. за управ. долаз. позив." "Позивање пратеће апликације" - "Апликација за помоћ" "Аплик. Пројекција у аутомобилу" + "Не подржава профил за Work" "Напомена: Ако рестартујете уређај и подесили сте закључавање екрана, ова апликација не може да се покрене док не откључате уређај." + "Помоћник ће моћи да чита информације о апликацијама које се користе у систему, укључујући информације видљиве на екрану или којима може да се приступа у оквиру апликација." "Дељење података о отклањању грешака" "Делите детаљне податке за отклањање грешака?" "%1$s жели да отпреми информације за отклањање грешака." diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml index c2f7ffd32..2f1614bd4 100644 --- a/res/values-sv/strings.xml +++ b/res/values-sv/strings.xml @@ -168,6 +168,11 @@ "Öppna" "Avinstallera" "Tvinga att avsluta" + "Inställningar" + "%s har fullständig åtkomst till din enhet" + "%s tillgänglighetstjänster har fullständig åtkomst till din enhet" + "%s får visa din skärm, dina åtgärder och inmatningar, utföra åtgärder och styra skärmen." + "Dessa tjänster får visa din skärm, dina åtgärder och inmatningar, utföra åtgärder och styra skärmen." "Standardappar" "Inga standardappar" "Standardinställning för jobbet" @@ -176,6 +181,7 @@ "Särskild åtkomst för app" "Ingen särskild åtkomst för app" "Inga appar" + "Assistentapp" "Webbläsarapp" "Appen Telefon" "Sms-app" @@ -184,13 +190,13 @@ "Appen Musik" "Appen Galleri" "Mobilapp för billäge" - - + "Omdirigeringsapp för samtal" "App för samtalsspärr" "Tillhörande samtalsapp" - "Assistentapp" "App för projicering i bilen" + "Arbetsprofiler stöds inte" "Obs! Om du startar om mobilen och har ställt in ett skärmlås kan appen inte startas förrän du låser upp mobilen." + "Assistenten kan läsa information om appar som används i systemet, inklusive information som visas på skärmen eller är åtkomlig i apparna." "Dela felsökningsinformation" "Vill du dela detaljerad felsökningsinformation?" "%1$s vill ladda upp felsökningsinformation." diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml index 730cdf4b4..496ee7166 100644 --- a/res/values-sw/strings.xml +++ b/res/values-sw/strings.xml @@ -168,6 +168,11 @@ "Fungua" "Ondoa" "Lazimisha kuzima" + "Mipangilio" + "%s ina idhini kamili ya kufikia kifaa chako" + "Huduma %s za ufikivu zina idhini kamili ya kufikia kifaa chako" + "%s inaweza kuona skrini, vitendo na maudhui unayoweka, kutekeleza vitendo na kudhibiti onyesho." + "Huduma hizi zinaweza kuona skrini, vitendo na maudhui unayoweka, kutekeleza vitendo na kudhibiti onyesho." "Programu chaguomsingi" "Hakuna programu chaguomsingi" "Programu chaguomsingi kazini" @@ -176,6 +181,7 @@ "Ufikiaji wa programu maalum" "Hamna kufikia programu maalum" "Hakuna programu" + "Programu ya mratibu" "Programu ya kivinjari" "Programu ya simu" "Programu ya SMS" @@ -184,13 +190,13 @@ "Programu ya muziki" "Programu ya matunzio" "Programu ya simu katika hali ya gari" - - + "Programu ya kuelekeza simu" "Programu ya kuchuja simu" "Programu ya kusaidia kupiga simu" - "Programu ya mratibu" "Programu ya Kuakisi Simu Garini" + "Haitumii wasifu wa kazini" "Kumbuka: Kama utazima kisha uwashe kifaa chako na uwe umeweka njia ya kufunga skrini, programu hii haitafanya kazi hadi ufungue kifaa chako." + "Programu ya Mratibu itaweza kusoma maelezo kuhusu programu unazotumia katika mfumo wako, ikiwa ni pamoja na maelezo yanayoonekana kwenye skrini yako au yanayoweza kufikiwa ndani ya programu." "Shiriki Data ya Utatuzi" "Ungependa kushiriki data ya kina ya utatuzi?" "%1$s inataka kupakia maelezo ya utatuzi." diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml index e6b75297c..57daa0d59 100644 --- a/res/values-ta/strings.xml +++ b/res/values-ta/strings.xml @@ -168,6 +168,16 @@ "திற" "நிறுவல் நீக்கு" "உடனே நிறுத்து" + + + + + + + + + + "இயல்புநிலை ஆப்ஸ்" "இயல்புநிலை ஆப்ஸ் இல்லை" "பணிக்கான இயல்பு நிலை ஆப்ஸ்" @@ -176,6 +186,7 @@ "ஆப்ஸிற்கான சிறப்பு அணுகல்" "ஆப்ஸிற்கு சிறப்பு அணுகல் இல்லை" "ஆப்ஸ் இல்லை" + "அசிஸ்ட் ஆப்ஸ்" "உலாவி ஆப்ஸ்" "மொபைல் ஆப்ஸ்" "மெசேஜ் ஆப்ஸ்" @@ -184,13 +195,15 @@ "மியூசிக் ஆப்ஸ்" "கேலரி ஆப்ஸ்" "கார் மோடுக்கான மொபைல் ஆப்ஸ்" - - + "அழைப்பைத் திருப்பிவிடும் ஆப்ஸ்" "அழைப்புத் திரை ஆப்ஸ்" "அழைப்புக்கான கம்பேனியன் ஆப்ஸ்" - "அசிஸ்ட் ஆப்ஸ்" "கார் காட்சிப்படுத்தல் ஆப்ஸ்" + + "கவனத்திற்கு: திரைப் பூட்டு அமைக்கப்பட்டிருக்கும் நிலையில் உங்கள் மொபைலை மீண்டும் தொடங்கினால் அன்லாக் செய்யப்படும்வரை இந்த ஆப்ஸ் இயங்காது." + + "பிழைதிருத்தத் தரவைப் பகிர்தல்" "விரிவான பிழைதிருத்தத் தகவலைப் பகிரவா?" "பிழைதிருத்தத் தகவலை %1$s பதிவேற்ற விரும்புகிறது." diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml index 36aa4a057..8f258db42 100644 --- a/res/values-te/strings.xml +++ b/res/values-te/strings.xml @@ -168,6 +168,16 @@ "తెరవండి" "అన్ఇన్‌స్టాల్ చేయి" "ఫోర్స్ స్టాప్" + + + + + + + + + + "డిఫాల్ట్ యాప్‌లు" "డిఫాల్ట్ యాప్‌లు ఏవీ లేవు" "కార్యాలయం కోసం డిఫాల్ట్" @@ -176,6 +186,7 @@ "ప్రత్యేక యాప్ యాక్సెస్" "ప్రత్యేక యాప్ యాక్సెస్ లేదు" "ఏ యాప్‌కి లేదు" + "సహాయక యాప్" "బ్రౌజర్ యాప్" "ఫోన్ యాప్" "SMS యాప్" @@ -184,13 +195,15 @@ "సంగీత యాప్" "గ్యాలరీ యాప్‌" "కార్ మోడ్ ఫోన్ యాప్" - - + "కాల్ మళ్లింపు యాప్" "కాల్ స్క్రీనింగ్ యాప్" "కాల్ సహచర యాప్" - "సహాయక యాప్" "కార్ ప్రొజెక్షన్ యాప్" + + "చిన్న గమనిక: మీరు భద్రత కోసం స్క్రీన్ లాక్‌ని సెటప్‌ చేసి పెట్టుకున్నారు పైగా మీ పరికరాన్ని పునఃప్రారంభించినట్టున్నారు కనుక స్క్రీన్ లాక్ అయ్యిపోయింది. మీరు పాస్‌వర్డ్‌ని నమోదు చేసేవరకూ ఈ యాప్ ప్రారంభం కాదు." + + "డీబగ్గింగ్ డేటాను షేర్ చేయండి" "వివరణాత్మక డీబగ్గింగ్ డేటాను షేర్ చేయాలా?" "%1$sడీబగ్గింగ్ సమాచారాన్ని అప్‌లో డ్ చేయదలుచుకుంటున్నారు." diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml index 014f180ee..41f2508c9 100644 --- a/res/values-th/strings.xml +++ b/res/values-th/strings.xml @@ -168,6 +168,16 @@ "เปิด" "ถอนการติดตั้ง" "บังคับให้หยุด" + + + + + + + + + + "แอปเริ่มต้น" "ไม่มีแอปเริ่มต้น" "ค่าเริ่มต้นสำหรับงาน" @@ -176,6 +186,7 @@ "สิทธิ์เข้าถึงพิเศษของแอป" "ไม่มีสิทธิ์เข้าถึงพิเศษของแอป" "ไม่มีแอป" + "แอปผู้ช่วย" "แอปเบราว์เซอร์" "แอปโทรศัพท์" "แอป SMS" @@ -184,13 +195,15 @@ "แอปเพลง" "แอปแกลเลอรี" "แอปโทรศัพท์ในโหมดรถยนต์" - - + "แอปเปลี่ยนเส้นทางสายเรียกเข้า" "แอปสกรีนสายเรียกเข้า" "แอปที่ใช้ร่วมกับการโทร" - "แอปผู้ช่วย" "แอป Car Projection" + + "หมายเหตุ: หากคุณรีสตาร์ทอุปกรณ์และตั้งการล็อกหน้าจอไว้ แอปนี้จะเริ่มทำงานไม่ได้จนกว่าคุณจะปลดล็อกอุปกรณ์" + + "แชร์ข้อมูลการแก้ไขข้อบกพร่อง" "แชร์ร์ข้อมูลการแก้ไขข้อบกพร่องโดยละเอียดไหม" "%1$s ต้องการอัปโหลดข้อมูลการแก้ไขข้อบกพร่อง" diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml index 3b4bf6e40..328058806 100644 --- a/res/values-tl/strings.xml +++ b/res/values-tl/strings.xml @@ -168,6 +168,11 @@ "Buksan" "I-uninstall" "Sapilitang ihinto" + "Mga Setting" + "May kumpletong access ang %s sa iyong device" + "%s (na) serbisyo sa pagiging naa-access ang may kumpletong access sa iyong device" + "Magagawa ng %s na tingnan ang iyong screen, mga pagkilos, at mga input, magsagawa ng mga pagkilos, at kontrolin ang display." + "Magagawa ng mga serbisyong ito na tingnan ang iyong screen, mga pagkilos, at mga input, magsagawa ng mga pagkilos, at kontrolin ang display." "Mga default na app" "Walang default na app" "Default para sa trabaho" @@ -176,6 +181,7 @@ "Espesyal na app access" "Walang espesyal na app access" "Walang app" + "Assist app" "Browser app" "Phone app" "SMS app" @@ -184,13 +190,13 @@ "Music app" "Gallery app" "App na telepono ng car mode" - - + "App sa pag-redirect ng tawag" "App ng pag-screen ng tawag" "Kasamang app sa pagtawag" - "Assist app" "Car Projection app" + "Hindi sinusuportahan ang profile sa trabaho" "Tandaan: Kung ire-restart mo ang iyong device at may nakatakdang lock ng screen, hindi makakapagsimula ang app na ito hanggang sa i-unlock mo ang iyong device." + "Mababasa ng assistant ang impormasyon tungkol sa mga app na ginagamit sa iyong system, kasama ang impormasyong makikita sa screen mo o maa-access sa mga app." "Ibahagi ang Data sa Pag-debug" "Ibahagi ang nakadetalyeng data sa pag-debug?" "Gustong mag-upload ng %1$s ng impormasyon sa pag-debug." diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml index 4903d30c8..25a59d05e 100644 --- a/res/values-tr/strings.xml +++ b/res/values-tr/strings.xml @@ -168,6 +168,11 @@ "Aç" "Yüklemeyi Kaldır" "Zorla durdur" + "Ayarlar" + "%s hizmetinin cihazınıza tam erişimi var" + "%s erişilebilirlik hizmetinin, cihazınıza tam erişimi var" + "%s ekranınızı, işlemlerinizi ve girişlerinizi görebilir, işlemler gerçekleştirebilir ve ekranı kontrol edebilir." + "Bu hizmetler ekranınızı, işlemlerinizi ve girişlerinizi görebilir, işlemler gerçekleştirebilir ve ekranı kontrol edebilir." "Varsayılan uygulamalar" "Varsayılan uygulama yok" "İş için varsayılan" @@ -176,6 +181,7 @@ "Özel uygulama erişimi" "Özel uygulama erişimi yok" "Uygulama yok" + "Yardım uygulaması" "Tarayıcı uygulaması" "Telefon uygulaması" "SMS uygulaması" @@ -184,13 +190,13 @@ "Müzik uygulaması" "Galeri uygulaması" "Araba modu telefon uygulaması" - - + "Arama yönlendirme uygulaması" "Arama süzme uygulaması" "Arama tamamlayıcı uygulaması" - "Yardım uygulaması" "Car Projection uygulaması" + "İş profili desteklenmiyor" "Not: Cihazınızı yeniden başlatırsanız ve ekran kilidi kullanıyorsanız, cihazınızın kilidini açmadan bu uygulama başlayamaz." + "Asistan, ekranınızda görünür olan veya uygulamaların içinden erişilebilen bilgiler dahil olmak üzere sisteminizde kullanılan uygulamalar hakkındaki bilgileri okuyabilecektir." "Hata Ayıklama Verilerini Paylaş" "Ayrıntılı hata ayıklama verileri paylaşılsın mı?" "%1$s, hata ayıklama bilgilerini yüklemek istiyor." diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml index 7e6061b76..3baa55e33 100644 --- a/res/values-uk/strings.xml +++ b/res/values-uk/strings.xml @@ -178,6 +178,16 @@ "Відкрити" "Видалити" "Примусово припинити" + + + + + + + + + + "Додатки за умовчанням" "Немає додатків за умовчанням" "Для роботи за умовчанням" @@ -186,6 +196,7 @@ "Спеціальний доступ" "Немає спеціального доступу" "Немає додатків" + "Помічник" "Додаток для веб-перегляду" "Додаток Телефон" "Додаток для SMS" @@ -194,13 +205,15 @@ "Додаток Музика" "Додаток Галерея" "Телефонний додаток для режиму авто" - - + "Додаток для переспрямування викликів" "Додаток для керування викликами" "Супутній додаток для викликів" - "Помічник" "Додаток для проекції на екран авто" + + "Примітка. Якщо після перезавантаження ввімкнеться екран блокування, цей додаток не запуститься, доки ви не розблокуєте пристрій." + + "Поділитися даними про налагодження" "Поділитися детальними даними про налагодження?" "Додаток %1$s хоче завантажити інформацію про налагодження." diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml index c3ada0782..fc381a5fd 100644 --- a/res/values-ur/strings.xml +++ b/res/values-ur/strings.xml @@ -168,6 +168,11 @@ "کھولیں" "اَن انسٹال کریں" "زبردستی روکیں" + "ترتیبات" + "%s کو آپ کے آلہ تک مکمل رسائی حاصل ہے" + "%s ایکسیسبیلٹی سروسز کو آپ کے آلہ تک مکمل رسائی حاصل ہے" + "%s آپ کی اسکرین، کارروائیوں اور ان پٹس کو دیکھ، کارروائیاں کر اور ڈسپلے کو کنٹرول کر سکتی ہے۔" + "یہ سروسز آپ کی اسکرین، کارروائیوں اور ان پٹس کو دیکھ، کارروائیاں کر اور ڈسپلے کو کنٹرول کر سکتی ہیں۔" "ڈیفالٹ ایپس" "کوئی ڈیفالٹ ایپ نہیں ہے" "کام کیلئے ڈیفالٹ" @@ -176,6 +181,7 @@ "خاص ایپ تک رسائی" "خاص ایپ تک کوئی رسائی نہیں ہے" "کوئی ایپ نہیں ہے" + "معاون ایپ" "براؤزر ایپ" "فون ایپ" "‏SMS ایپ" @@ -184,13 +190,13 @@ "موسیقی ایپ" "گیلری ایپ" "کار موڈ والی فون ایپ" - - + "کال ری ڈائریکٹنگ اپپ" "کال اسکریننگ اپپ" "ساتھی اپپ برائے کال" - "معاون ایپ" "‏Car Projection ایپ" + "دفتری پروفائل کا تعاون نہیں کرتا ہے" "نوٹ: اگر آپ اپنے آلہ کو دوبارہ شروع کرتے ہیں اور آپ کے پاس اسکرین لاک کا سیٹ ہے تو یہ ایپ تب تک شروع نہیں ہو سکتی جب تک آپ اپنا آلہ غیر مقفل نہ کر لیں۔" + "اسسٹنٹ آپ کے سسٹم پر زیر استعمال ایپس کے بارے میں معلومات، بشمول آپ کی اسکرین پر نظر آنے والی یا ایپس کے اندر قابل رسائی معلومات پڑھ سکے گی۔" "ڈیبگنگ ڈیٹا کا اشتراک کریں" "ڈیبگنگ کے تفصیلی ڈیٹا کا اشتراک کریں؟" "%1$s ڈیبگنگ کی معلومات اپ لوڈ کرنا چاہتی ہے۔" diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml index 85f47bb55..ddab18083 100644 --- a/res/values-uz/strings.xml +++ b/res/values-uz/strings.xml @@ -168,6 +168,11 @@ "Ochiq" "Olib tashlash" "Majburan toʻxtatish" + "Sozlamalar" + "%s xizmati qurilmangizdan butunlay foydalana oladi" + "%s ta maxsus xizmat qurilmangizdan butunlay foydalana oladi" + "%s ekraningiz, bajargan amallaringiz va yozuvlaringizni koʻra oladi hamda ekraningizni boshqa oladi" + "Bu xizmatlar ekraningiz, bajargan amallaringiz va yozuvlaringizni koʻra oladi hamda ekraningizni boshqara oladi" "Birlamchi ilovalar" "Birlamchi ilovalar mavjud emas" "Ish uchun birlamchi" @@ -176,6 +181,7 @@ "Maxsus ruxsatlar" "Maxsus ilova ruxsatlari yoʻq" "Hech qanday ilova topilmadi" + "Yordamchi ilova" "Brauzer ilovasi" "Telefon ilovasi" "SMS ilovasi" @@ -184,13 +190,13 @@ "Musiqa ilovasi" "Galereya ilovasi" "Mashina uchun telefon ilovasi" - - + "Chaqiruvlarni uzatish ilovasi" "Kiruvchi chaqiruvlar ilovasi" "Chaqiruvlar ilovasiga sherik" - "Yordamchi ilova" "Car Projection ilovasi" + "Ishchi profildan foydalanish imkonsiz" "Eslatma: Agar qurilmani qayta ishga tushirsangiz va ekran qulfi sozlangan boʻlsa, bu ilova to qurilmangiz qulfdan chiqarilmaguncha ishga tushmaydi." + "Assistent tizimda ishlatilayotgan ilovalar haqidagi axborotni, masalan, ekranga chiqib turgan yoki ilovalar orqali kiriladigan axborotlarni oʻqiy oladi." "Nosozliklarni aniqlash axborotini ulashish" "Nosozliklarni aniqlashga oid axborot ulashilsinmi?" "%1$s ilovasi nosozliklarni aniqlash axborotini yuklamoqchi." diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml index 47505a1f3..4d56f77c0 100644 --- a/res/values-vi/strings.xml +++ b/res/values-vi/strings.xml @@ -168,6 +168,16 @@ "Mở" "Gỡ cài đặt" "Buộc dừng" + + + + + + + + + + "Ứng dụng mặc định" "Không có ứng dụng mặc định" "Ứng dụng mặc định cho công việc" @@ -176,6 +186,7 @@ "Quyền truy cập đặc biệt" "Không có quyền truy cập đặc biệt" "Không có ứng dụng" + "Ứng dụng trợ lý" "Ứng dụng trình duyệt" "Ứng dụng điện thoại" "Ứng dụng SMS" @@ -184,13 +195,15 @@ "Ứng dụng âm nhạc" "Ứng dụng thư viện" "Ứng dụng điện thoại cho chế độ ô tô" - - + "Ứng dụng chuyển hướng cuộc gọi" "Ứng dụng sàng lọc cuộc gọi" "Ứng dụng đồng hành cuộc gọi" - "Ứng dụng trợ lý" "Ứng dụng Chiếu trên ô tô" + + "Lưu ý: Nếu bạn khởi động lại thiết bị và đặt khóa màn hình, thì ứng dụng này sẽ không thể khởi động cho đến khi bạn mở khóa thiết bị." + + "Chia sẻ dữ liệu gỡ lỗi" "Bạn muốn chia sẻ dữ liệu gỡ lỗi chi tiết?" "%1$s muốn tải thông tin gỡ lỗi lên." diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml index f574bcc23..e07e70421 100644 --- a/res/values-zh-rCN/strings.xml +++ b/res/values-zh-rCN/strings.xml @@ -168,6 +168,16 @@ "打开" "卸载" "强行停止" + + + + + + + + + + "默认应用" "没有任何默认应用" "默认工作应用" @@ -176,6 +186,7 @@ "特殊应用权限" "没有特殊应用权限" "没有应用" + "辅助应用" "浏览器应用" "电话应用" "短信应用" @@ -184,13 +195,15 @@ "音乐应用" "图库应用" "车载模式手机应用" - - + "通话转接应用" "选接电话应用" "通话配套应用" - "辅助应用" "汽车投影应用" + + "注意:如果您重启设备并设置了屏幕锁定,则必须将设备解锁才能运行此应用。" + + "分享调试数据" "是否分享详细调试数据?" "%1$s请求上传调试信息。" diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml index 43dc1d9f5..44fe511cb 100644 --- a/res/values-zh-rHK/strings.xml +++ b/res/values-zh-rHK/strings.xml @@ -168,6 +168,16 @@ "開啟" "解除安裝" "強制停止" + + + + + + + + + + "預設應用程式" "沒有預設應用程式" "預設用於工作" @@ -176,6 +186,7 @@ "特別應用程式權限" "沒有特別應用程式權限" "沒有應用程式" + "小幫手應用程式" "瀏覽器應用程式" "手機應用程式" "短訊應用程式" @@ -184,13 +195,15 @@ "音樂應用程式" "相片集應用程式" "車用模式手機應用程式" - - + "通話重新導向應用程式" "來電篩選應用程式" "通話隨附應用程式" - "小幫手應用程式" "「汽車投影」應用程式" + + "請注意:如果您重新啟動裝置並設定了螢幕鎖定,就必須先將裝置解鎖,才可執行這個應用程式。" + + "分享偵錯資料" "要分享詳細的偵錯資料嗎?" "「%1$s」要求上載偵錯資料。" diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml index add445b62..85b6ececb 100644 --- a/res/values-zh-rTW/strings.xml +++ b/res/values-zh-rTW/strings.xml @@ -168,6 +168,16 @@ "開啟" "解除安裝" "強制停止" + + + + + + + + + + "預設應用程式" "沒有任何預設應用程式" "預設的工作應用程式" @@ -176,6 +186,7 @@ "特殊應用程式存取權" "沒有特殊應用程式存取權" "沒有可用的應用程式" + "小幫手應用程式" "瀏覽器應用程式" "「電話」應用程式" "簡訊應用程式" @@ -184,13 +195,15 @@ "音樂應用程式" "圖片庫應用程式" "車用模式手機應用程式" - - + "通話轉接應用程式" "來電過濾應用程式" "通話隨附應用程式" - "小幫手應用程式" "車輛投影應用程式" + + "注意:如果你重新啟動裝置並設定了螢幕鎖定,你必須先將裝置解鎖,才能執行這個應用程式。" + + "分享除錯資料" "要分享詳細的除錯資料嗎?" "「%1$s」要求上傳除錯資訊。" diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml index d086817ff..448a81fc3 100644 --- a/res/values-zu/strings.xml +++ b/res/values-zu/strings.xml @@ -168,6 +168,11 @@ "Vula" "Khipha" "Phoqelela ukuma" + "Izilungiselelo" + "I-%s inokufinyelela okugcwele kudivayisi yakho" + "%s amasevisi okufinyeleleka anokufinyelela okugcwele kudivayisi yakho" + "I-%s ingabuka isikrini sakho, izenzo, nokokufaka, yenze izenzo, iphinde ilawule isiboniso." + "Lawa masevisi angabuka isikrini sakho, izenzo, nokokufaka, enze izenzo, aphinde alawule isiboniso." "Izinhlelo zokusebenza ezizenzakalelayo" "Azikho izinhlelo zokusebenza ezizenzakalelayo" "Okuzenzakalelayo kokusebenza" @@ -176,6 +181,7 @@ "Ukungena kohlelo okukhethekile" "Akukho ukungena okukhethekile" "Azikho izinhlelo zokusebenza" + "Uhlelo lokusebenza lokusiza" "Uhlelo lokusebenza lwesiphequluli" "Uhlelo lokusebenza lwefoni" "Uhlelo lokusebenza lwe-SMS" @@ -184,13 +190,13 @@ "Uhlelo lokusebenza lomculo" "Uhlelo lokusebenza lwegalari" "I-app yefoni yemoti yemoto" - - + "Uhlelo lokusebenza lokuqondisa kabusha ikholi" "I-app lokuskrina lokushaya" "I-app lokuhambisana lokushaya" - "Uhlelo lokusebenza lokusiza" "Uhlelo lokusebenza lokuphrojektha kwemoto" + "Ayisekeli iphrofayela yokusebenza" "Qaphela: Uma uqala kabusha idivayisi yakho futhi usethe ukukhiya kwesikrini, lolu hlelo lokusebenza alukwazi ukuqala uze uvule idivayisi yakho." + "Isilekeleli sizokwazi ukufunda ulwazi mayelana nezinhlelo zokusebenza ezisetshenziswayo kusistimu yakho, ezifaka ulwazi olubonakala kusikrini sakho noma ezifinyeleleka ngaphakathi kwezinhlelo zokusebenza." "Yabelana ngedatha yokususa iphutha" "Yabelana ngedatha enemininingwane yokususa iphutha?" "I-%1$s ingathanda ukulayisha ulwazi lokususa iphutha." -- GitLab From a20fba03ce8d6b5f60624590c87028b52c62c987 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Wed, 20 Feb 2019 19:40:22 -0800 Subject: [PATCH 387/701] Update titles Use the new titles for permissions screens. Bug: 125018087 Test: View PermissionsUsageFragment and ManageStandardPermissionsFragment. Change-Id: I2ca5107af5ca20d6ef36471343bff36c06aeac10 --- res/values/strings.xml | 8 ++++++-- .../ui/handheld/ManageStandardPermissionsFragment.java | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 41e60eac7..ae1f41c0e 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -98,6 +98,10 @@ App permissions + + + Permission manager + Don\'t ask again @@ -130,7 +134,7 @@ Recent usage - View details + View Permissions Dashboard Show system @@ -253,7 +257,7 @@ - Permissions usage + Dashboard diff --git a/src/com/android/packageinstaller/permission/ui/handheld/ManageStandardPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/ManageStandardPermissionsFragment.java index fd527e228..f2ba07a85 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/ManageStandardPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/ManageStandardPermissionsFragment.java @@ -79,7 +79,7 @@ public final class ManageStandardPermissionsFragment extends ManagePermissionsFr public void onStart() { super.onStart(); - getActivity().setTitle(com.android.permissioncontroller.R.string.app_permissions); + getActivity().setTitle(com.android.permissioncontroller.R.string.app_permission_manager); } @Override -- GitLab From 10ec86773a17b08898d65f4cf702d04b89239123 Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Thu, 21 Feb 2019 13:29:33 -0800 Subject: [PATCH 388/701] Mark UI tests as flaky and restore role tests for presubmit. These UI tests will be excluded from presubmit. Bug: 125404675 Bug: 123376916 Test: atest RoleManagerTest Change-Id: Idbb1f7f0fadf54ab5d5b2dc362a40c22c2951f9b --- res/xml/TEST_MAPPING | 9 +++++++-- src/com/android/packageinstaller/role/TEST_MAPPING | 9 +++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/res/xml/TEST_MAPPING b/res/xml/TEST_MAPPING index 97a0415a4..43d15a49e 100644 --- a/res/xml/TEST_MAPPING +++ b/res/xml/TEST_MAPPING @@ -1,7 +1,12 @@ { - "postsubmit": [ + "presubmit": [ { - "name": "CtsRoleTestCases" + "name": "CtsRoleTestCases", + "options": [ + { + "exclude-annotation": "androidx.test.filters.FlakyTest" + } + ] } ] } diff --git a/src/com/android/packageinstaller/role/TEST_MAPPING b/src/com/android/packageinstaller/role/TEST_MAPPING index 97a0415a4..43d15a49e 100644 --- a/src/com/android/packageinstaller/role/TEST_MAPPING +++ b/src/com/android/packageinstaller/role/TEST_MAPPING @@ -1,7 +1,12 @@ { - "postsubmit": [ + "presubmit": [ { - "name": "CtsRoleTestCases" + "name": "CtsRoleTestCases", + "options": [ + { + "exclude-annotation": "androidx.test.filters.FlakyTest" + } + ] } ] } -- GitLab From 731b520823fa7d6f0a50617a8d5b66f788fe2a4e Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Tue, 5 Feb 2019 09:28:02 -0800 Subject: [PATCH 389/701] Show dialog when trying to change location provider permission. GMS Core is the location provider on the device and so the permission cannot be disabled. Instead of having clicks on it go to a disabled tri-state screen, restore the P behavior of popping up a dialog that can redirect users to the Location setting. Fixes: 123902223 Test: Click on GMS Core location on four different screens and get this dialog. Test: Click on other permissions and get the normal tri-state. Change-Id: Ic4ec22dea46405d4800010dec437822965f351ec --- AndroidManifest.xml | 4 ++ .../permission/ui/AppPermissionActivity.java | 9 +++ .../ui/LocationProviderInterceptDialog.java | 72 +++++++++++++++++++ 3 files changed, 85 insertions(+) create mode 100644 src/com/android/packageinstaller/permission/ui/LocationProviderInterceptDialog.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 6d401305d..4d22a50b6 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -133,6 +133,10 @@ android:excludeFromRecents="true" android:theme="@android:style/Theme.DeviceDefault.Light.Dialog.NoActionBar" /> + + diff --git a/src/com/android/packageinstaller/permission/ui/AppPermissionActivity.java b/src/com/android/packageinstaller/permission/ui/AppPermissionActivity.java index f2a87b503..e00c4c527 100644 --- a/src/com/android/packageinstaller/permission/ui/AppPermissionActivity.java +++ b/src/com/android/packageinstaller/permission/ui/AppPermissionActivity.java @@ -64,6 +64,15 @@ public final class AppPermissionActivity extends FragmentActivity { return; } + if (LocationUtils.isLocationGroupAndProvider(this, permissionName, + packageName)) { + Intent intent = new Intent(this, LocationProviderInterceptDialog.class); + intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName); + startActivity(intent); + finish(); + return; + } + if (LocationUtils.isLocationGroupAndControllerExtraPackage( this, permissionName, packageName)) { // Redirect to location controller extra package settings. diff --git a/src/com/android/packageinstaller/permission/ui/LocationProviderInterceptDialog.java b/src/com/android/packageinstaller/permission/ui/LocationProviderInterceptDialog.java new file mode 100644 index 000000000..c0b7e6ace --- /dev/null +++ b/src/com/android/packageinstaller/permission/ui/LocationProviderInterceptDialog.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2019 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.packageinstaller.permission.ui; + +import android.app.AlertDialog; +import android.content.Intent; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.os.Bundle; +import android.provider.Settings; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentActivity; + +import com.android.packageinstaller.permission.utils.Utils; +import com.android.permissioncontroller.R; + +/** + * A dialog saying that you cannot change the location provider's location permission. + */ +public final class LocationProviderInterceptDialog extends FragmentActivity { + private static final String LOG_TAG = LocationProviderInterceptDialog.class.getSimpleName(); + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + String packageName = getIntent().getStringExtra(Intent.EXTRA_PACKAGE_NAME); + if (packageName == null) { + Log.i(LOG_TAG, "Missing mandatory argument EXTRA_PACKAGE_NAME"); + finish(); + return; + } + + new AlertDialog.Builder(this) + .setIcon(R.drawable.ic_dialog_alert_material) + .setTitle(android.R.string.dialog_alert_title) + .setMessage(getString(R.string.location_warning, + Utils.getAppLabel(getPackageInfo(packageName).applicationInfo, this))) + .setNegativeButton(R.string.ok, null) + .setPositiveButton(R.string.location_settings, (dialog, which) -> + startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS))) + .setOnDismissListener((dialog) -> finish()) + .show(); + } + + private @Nullable PackageInfo getPackageInfo(@NonNull String packageName) { + try { + return getPackageManager().getPackageInfo(packageName, PackageManager.GET_PERMISSIONS); + } catch (PackageManager.NameNotFoundException e) { + Log.i(LOG_TAG, "No package: " + packageName, e); + finish(); + return null; + } + } +} -- GitLab From f62eb69beeabf96dcdda29b679cb212ada19cd7b Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Fri, 22 Feb 2019 15:48:55 -0800 Subject: [PATCH 390/701] Use correct force stop icon. I had accidentally used a copy of the uninstall icon. Note that these will hopefully go away once we move all of this functionality into SettingsLib. Test: Open AppPermissionsFragment and see correct icon. Change-Id: Ia4bb535d74ad5eb4d2a9401d539ebe93934c250d --- res/drawable/ic_force_stop.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/res/drawable/ic_force_stop.xml b/res/drawable/ic_force_stop.xml index 84e8982cf..ca9f02f3d 100644 --- a/res/drawable/ic_force_stop.xml +++ b/res/drawable/ic_force_stop.xml @@ -21,11 +21,11 @@ android:viewportHeight="24"> + android:pathData="M12,5.99L19.53,19H4.47L12,5.99M12,2L1,21h22L12,2L12,2z"/> + android:pathData="M13,16l-2,0l0,2l2,0l0,-2z"/> + android:pathData="M13,10l-2,0l0,4l2,0l0,-4z"/> \ No newline at end of file -- GitLab From 3af151de470bbc94612e16010bcbbaa51189bdc2 Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Mon, 25 Feb 2019 10:59:09 -0800 Subject: [PATCH 391/701] Do not kill admin when changing own permissions Test: Made device admin change own permissions Fixes: 126149273 Change-Id: If89cd674a7e2545557d6ac34ce9f9c39ed55ab2e --- .../permission/service/PermissionControllerServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java b/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java index 9bf794183..f04634ca5 100644 --- a/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java +++ b/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java @@ -552,7 +552,7 @@ public final class PermissionControllerServiceImpl extends PermissionControllerS return false; } - group.persistChanges(true); + group.persistChanges(!callerPackageName.equals(packageName)); } return true; -- GitLab From 824afe44334e756bd898a7197c422f7c04a2d562 Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Mon, 25 Feb 2019 10:59:09 -0800 Subject: [PATCH 392/701] Do not kill admin when changing own permissions Test: Made device admin change own permissions Fixes: 126149273 Change-Id: If89cd674a7e2545557d6ac34ce9f9c39ed55ab2e (cherry picked from commit 3af151de470bbc94612e16010bcbbaa51189bdc2) --- .../permission/service/PermissionControllerServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java b/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java index 9bf794183..f04634ca5 100644 --- a/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java +++ b/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java @@ -552,7 +552,7 @@ public final class PermissionControllerServiceImpl extends PermissionControllerS return false; } - group.persistChanges(true); + group.persistChanges(!callerPackageName.equals(packageName)); } return true; -- GitLab From f99be9ade9654ce2abefb040c17b5699c19c863f Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Mon, 25 Feb 2019 16:39:04 -0800 Subject: [PATCH 393/701] Move CtsDevicePolicyManagerTestCases to postsubmit Current pre-submit has to be 1000% reliable and the test suite is occasionally flaky. We should remove the suite back once flakiness can be dealt with. Test: TH Fixes: 126216313 Change-Id: I6665c779c4bdb49273d6e6b570868427a777ec4d --- .../android/packageinstaller/permission/service/TEST_MAPPING | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/com/android/packageinstaller/permission/service/TEST_MAPPING b/src/com/android/packageinstaller/permission/service/TEST_MAPPING index ff5740e2d..a1175f873 100644 --- a/src/com/android/packageinstaller/permission/service/TEST_MAPPING +++ b/src/com/android/packageinstaller/permission/service/TEST_MAPPING @@ -18,7 +18,9 @@ "include-filter": "android.backup.cts.PermissionTest" } ] - }, + } + ], + "postsubmit": [ { "name": "CtsDevicePolicyManagerTestCases", "options": [ -- GitLab From 7380bf8d3f680f32d027a7106e454e9134555edb Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Mon, 25 Feb 2019 15:51:30 -0800 Subject: [PATCH 394/701] Only kill when needed when changing permissions Only kill app when an app-op actually changed. Do not call revokePermission if permission is already revoked. Even when the permission is alrady revoked, calling this method will kill the app the permission belongs to. Also, apply all device policy state and then perist the state for the whole app at one. Before we persisted after every individual permission which caused permissions to be temporarily revoked and then re-granted. Test: Set up device with device-owner, set up work-profile Fixes: 126185337, 126326421 Change-Id: Id28caebd36d0c66e83ee6ab4299f0ccb3bc6b488 --- .../permission/model/AppPermissionGroup.java | 97 +++++++++++++------ .../permission/model/AppPermissions.java | 10 +- .../permission/service/BackupHelper.java | 4 +- .../PermissionControllerServiceImpl.java | 28 ++++-- .../handheld/ReviewPermissionsFragment.java | 2 +- 5 files changed, 96 insertions(+), 45 deletions(-) diff --git a/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java b/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java index f26d65740..b6a447c78 100644 --- a/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java +++ b/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java @@ -26,7 +26,6 @@ import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE; import static android.app.AppOpsManager.MODE_ALLOWED; import static android.app.AppOpsManager.MODE_FOREGROUND; import static android.app.AppOpsManager.MODE_IGNORED; -import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import android.app.ActivityManager; @@ -628,6 +627,25 @@ public final class AppPermissionGroup implements Comparable return grantRuntimePermissions(fixedByTheUser, null); } + /** + * Set mode of an app-op if needed. + * + * @param op The op to set + * @param uid The uid the app-op belongs top + * @param mode The new mode + * + * @return {@code true} iff app-op was changed + */ + private boolean setAppOpMode(@NonNull String op, int uid, int mode) { + int currentMode = mAppOps.unsafeCheckOpRaw(op, uid, mPackageInfo.packageName); + if (currentMode == mode) { + return false; + } + + mAppOps.setUidMode(op, uid, mode); + return true; + } + /** * Allow the app op for a permission/uid. * @@ -649,8 +667,12 @@ public final class AppPermissionGroup implements Comparable * * @param permission The permission which has an appOps that should be allowed * @param uid The uid of the process the app op if for + * + * @return {@code true} iff app-op was changed */ - private void allowAppOp(Permission permission, int uid) { + private boolean allowAppOp(Permission permission, int uid) { + boolean wasChanged = false; + if (permission.isBackgroundPermission()) { ArrayList foregroundPermissions = permission.getForegroundPermissions(); @@ -658,7 +680,7 @@ public final class AppPermissionGroup implements Comparable for (int i = 0; i < numForegroundPermissions; i++) { Permission foregroundPermission = foregroundPermissions.get(i); if (foregroundPermission.isAppOpAllowed()) { - mAppOps.setUidMode(foregroundPermission.getAppOp(), uid, MODE_ALLOWED); + wasChanged |= setAppOpMode(foregroundPermission.getAppOp(), uid, MODE_ALLOWED); } } } else { @@ -669,18 +691,20 @@ public final class AppPermissionGroup implements Comparable // The app requested a permission that has a background permission but it did // not request the background permission, hence it can never get background // access - mAppOps.setUidMode(permission.getAppOp(), uid, MODE_FOREGROUND); + wasChanged = setAppOpMode(permission.getAppOp(), uid, MODE_FOREGROUND); } else { if (backgroundPermission.isAppOpAllowed()) { - mAppOps.setUidMode(permission.getAppOp(), uid, MODE_ALLOWED); + wasChanged = setAppOpMode(permission.getAppOp(), uid, MODE_ALLOWED); } else { - mAppOps.setUidMode(permission.getAppOp(), uid, MODE_FOREGROUND); + wasChanged = setAppOpMode(permission.getAppOp(), uid, MODE_FOREGROUND); } } } else { - mAppOps.setUidMode(permission.getAppOp(), uid, MODE_ALLOWED); + wasChanged = setAppOpMode(permission.getAppOp(), uid, MODE_ALLOWED); } } + + return wasChanged; } /** @@ -846,8 +870,12 @@ public final class AppPermissionGroup implements Comparable * * @param permission The permission which has an appOps that should be disallowed * @param uid The uid of the process the app op if for + * + * @return {@code true} iff app-op was changed */ - private void disallowAppOp(Permission permission, int uid) { + private boolean disallowAppOp(Permission permission, int uid) { + boolean wasChanged = false; + if (permission.isBackgroundPermission()) { ArrayList foregroundPermissions = permission.getForegroundPermissions(); @@ -855,12 +883,15 @@ public final class AppPermissionGroup implements Comparable for (int i = 0; i < numForegroundPermissions; i++) { Permission foregroundPermission = foregroundPermissions.get(i); if (foregroundPermission.isAppOpAllowed()) { - mAppOps.setUidMode(foregroundPermission.getAppOp(), uid, MODE_FOREGROUND); + wasChanged |= setAppOpMode(foregroundPermission.getAppOp(), uid, + MODE_FOREGROUND); } } } else { - mAppOps.setUidMode(permission.getAppOp(), uid, MODE_IGNORED); + wasChanged = setAppOpMode(permission.getAppOp(), uid, MODE_IGNORED); } + + return wasChanged; } /** @@ -1134,7 +1165,9 @@ public final class AppPermissionGroup implements Comparable * app ops change. If this is set to {@code false} the * caller has to make sure to kill the app if needed. */ - public void persistChanges(boolean mayKillBecauseOfAppOpsChange) { + void persistChanges(boolean mayKillBecauseOfAppOpsChange) { + int uid = mPackageInfo.applicationInfo.uid; + int numPermissions = mPermissions.size(); boolean shouldKillApp = false; boolean shouldUpdateStorage = false; @@ -1147,8 +1180,13 @@ public final class AppPermissionGroup implements Comparable mPackageManager.grantRuntimePermission(mPackageInfo.packageName, permission.getName(), mUserHandle); } else { - mPackageManager.revokeRuntimePermission(mPackageInfo.packageName, - permission.getName(), mUserHandle); + boolean isCurrentlyGranted = mContext.checkPermission(permission.getName(), -1, + uid) == PERMISSION_GRANTED; + + if (isCurrentlyGranted) { + mPackageManager.revokeRuntimePermission(mPackageInfo.packageName, + permission.getName(), mUserHandle); + } } } @@ -1171,16 +1209,14 @@ public final class AppPermissionGroup implements Comparable if (permission.affectsAppOp()) { if (!permission.isSystemFixed()) { + // Enabling/Disabling an app op may put the app in a situation in which it has + // a handle to state it shouldn't have, so we have to kill the app. This matches + // the revoke runtime permission behavior. if (permission.isAppOpAllowed()) { - allowAppOp(permission, mPackageInfo.applicationInfo.uid); + shouldKillApp |= allowAppOp(permission, uid); } else { - disallowAppOp(permission, mPackageInfo.applicationInfo.uid); + shouldKillApp |= disallowAppOp(permission, uid); } - - // Enabling/Disabling an app op may put the app in a situation in which it has a - // handle to state it shouldn't have, so we have to kill the app. This matches - // the revoke runtime permission behavior. - shouldKillApp = true; } } @@ -1201,12 +1237,12 @@ public final class AppPermissionGroup implements Comparable // case, whenever any of the new split permissions are granted to an // app, we also grant them the legacy "Storage" permission. if (StorageManager.hasIsolatedStorage() && shouldUpdateStorage) { - boolean audioGranted = mPackageManager.checkPermission(READ_MEDIA_AUDIO, - mPackageInfo.packageName) == PERMISSION_GRANTED; - boolean videoGranted = mPackageManager.checkPermission(READ_MEDIA_VIDEO, - mPackageInfo.packageName) == PERMISSION_GRANTED; - boolean imagesGranted = mPackageManager.checkPermission(READ_MEDIA_IMAGES, - mPackageInfo.packageName) == PERMISSION_GRANTED; + boolean audioGranted = mContext.checkPermission(READ_MEDIA_AUDIO, + -1, uid) == PERMISSION_GRANTED; + boolean videoGranted = mContext.checkPermission(READ_MEDIA_VIDEO, + -1, uid) == PERMISSION_GRANTED; + boolean imagesGranted = mContext.checkPermission(READ_MEDIA_IMAGES, + -1, uid) == PERMISSION_GRANTED; if (!ArrayUtils.isEmpty(mPackageInfo.requestedPermissions)) { for (String permission : mPackageInfo.requestedPermissions) { @@ -1216,8 +1252,13 @@ public final class AppPermissionGroup implements Comparable mPackageManager.grantRuntimePermission(mPackageInfo.packageName, permission, mUserHandle); } else { - mPackageManager.revokeRuntimePermission(mPackageInfo.packageName, - permission, mUserHandle); + boolean isCurrentlyGranted = mContext.checkPermission(permission, -1, + uid) == PERMISSION_GRANTED; + + if (isCurrentlyGranted) { + mPackageManager.revokeRuntimePermission(mPackageInfo.packageName, + permission, mUserHandle); + } } } } diff --git a/src/com/android/packageinstaller/permission/model/AppPermissions.java b/src/com/android/packageinstaller/permission/model/AppPermissions.java index 125074f48..93e517a15 100644 --- a/src/com/android/packageinstaller/permission/model/AppPermissions.java +++ b/src/com/android/packageinstaller/permission/model/AppPermissions.java @@ -179,18 +179,22 @@ public final class AppPermissions { /** * If the changes to the permission groups were delayed, persist them now. + * + * @param mayKillBecauseOfAppOpsChange If the app may be killed if app ops change. If this is + * set to {@code false} the caller has to make sure to kill + * the app if needed. */ - public void persistChanges() { + public void persistChanges(boolean mayKillBecauseOfAppOpsChange) { if (mDelayChanges) { int numGroups = mGroups.size(); for (int i = 0; i < numGroups; i++) { AppPermissionGroup group = mGroups.get(i); - group.persistChanges(true); + group.persistChanges(mayKillBecauseOfAppOpsChange); AppPermissionGroup backgroundGroup = group.getBackgroundPermissions(); if (backgroundGroup != null) { - backgroundGroup.persistChanges(true); + backgroundGroup.persistChanges(mayKillBecauseOfAppOpsChange); } } } diff --git a/src/com/android/packageinstaller/permission/service/BackupHelper.java b/src/com/android/packageinstaller/permission/service/BackupHelper.java index ab0471624..d55d3f98a 100644 --- a/src/com/android/packageinstaller/permission/service/BackupHelper.java +++ b/src/com/android/packageinstaller/permission/service/BackupHelper.java @@ -17,7 +17,6 @@ package com.android.packageinstaller.permission.service; import static android.content.Context.MODE_PRIVATE; -import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED; import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; import static android.content.pm.PackageManager.GET_PERMISSIONS; @@ -53,7 +52,6 @@ import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; -import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.OutputStream; @@ -750,7 +748,7 @@ public class BackupHelper { } } - appPerms.persistChanges(); + appPerms.persistChanges(true); } } } diff --git a/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java b/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java index f04634ca5..09539d62e 100644 --- a/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java +++ b/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java @@ -286,7 +286,7 @@ public final class PermissionControllerServiceImpl extends PermissionControllerS if (!doDryRun) { int numChangedApps = appsWithRevokedPerms.size(); for (int i = 0; i < numChangedApps; i++) { - appsWithRevokedPerms.get(i).persistChanges(); + appsWithRevokedPerms.get(i).persistChanges(true); } } @@ -528,33 +528,41 @@ public final class PermissionControllerServiceImpl extends PermissionControllerS Collections.singletonList(unexpandedPermission), callerPkgInfo.applicationInfo.targetSdkVersion); + AppPermissions app = new AppPermissions(this, pkgInfo, false, null); + int numPerms = expandedPermissions.size(); for (int i = 0; i < numPerms; i++) { - String perm = expandedPermissions.get(i); - AppPermissionGroup group = AppPermissionGroup.create(this, pkgInfo, perm, true); + String permName = expandedPermissions.get(i); + AppPermissionGroup group = app.getGroupForPermission(permName); if (group == null || group.isSystemFixed()) { continue; } + Permission perm = group.getPermission(permName); + if (perm == null) { + continue; + } + switch (grantState) { case PERMISSION_GRANT_STATE_GRANTED: - group.getPermission(perm).setPolicyFixed(true); - group.grantRuntimePermissions(false, new String[]{perm}); + perm.setPolicyFixed(true); + group.grantRuntimePermissions(false, new String[]{permName}); break; case PERMISSION_GRANT_STATE_DENIED: - group.getPermission(perm).setPolicyFixed(true); - group.revokeRuntimePermissions(false, new String[]{perm}); + perm.setPolicyFixed(true); + group.revokeRuntimePermissions(false, new String[]{permName}); break; case PERMISSION_GRANT_STATE_DEFAULT: - group.getPermission(perm).setPolicyFixed(false); + perm.setPolicyFixed(false); break; default: return false; } - - group.persistChanges(!callerPackageName.equals(packageName)); } + app.persistChanges(grantState == PERMISSION_GRANT_STATE_DENIED + || !callerPackageName.equals(packageName)); + return true; } } diff --git a/src/com/android/packageinstaller/permission/ui/handheld/ReviewPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/ReviewPermissionsFragment.java index dd854b746..350448857 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/ReviewPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/ReviewPermissionsFragment.java @@ -211,7 +211,7 @@ public final class ReviewPermissionsFragment extends PreferenceFragmentCompat } } - mAppPermissions.persistChanges(); + mAppPermissions.persistChanges(true); } private void bindUi() { -- GitLab From 71072e357cad9e544412d252488225d415ff5f14 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Tue, 26 Feb 2019 09:54:40 -0800 Subject: [PATCH 395/701] Fix app permission widget icon centering. Fixes: 126316257 Test: View screen with and without widget enabled. Change-Id: I12f93a7827ae200207f4f843627e1f76e7ee3c73 --- res/layout/app_permission.xml | 4 ++-- res/values/dimens.xml | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/res/layout/app_permission.xml b/res/layout/app_permission.xml index e41ec2b46..c6e987687 100644 --- a/res/layout/app_permission.xml +++ b/res/layout/app_permission.xml @@ -91,8 +91,8 @@ android:id="@+id/permission_details" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginStart="@dimen/app_permission_detail_margin_start" - android:layout_marginTop="@dimen/app_permission_detail_margin_top" /> + android:gravity="center" + android:layout_marginStart="@dimen/app_permission_detail_margin_start" /> 16dp 16dp - 12dp 48dp 12dp -- GitLab From 3f49d6dbf1ce1bd8a9572164a382739f355675fa Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Mon, 25 Feb 2019 15:51:30 -0800 Subject: [PATCH 396/701] Only kill when needed when changing permissions Only kill app when an app-op actually changed. Do not call revokePermission if permission is already revoked. Even when the permission is alrady revoked, calling this method will kill the app the permission belongs to. Also, apply all device policy state and then perist the state for the whole app at one. Before we persisted after every individual permission which caused permissions to be temporarily revoked and then re-granted. Test: Set up device with device-owner, set up work-profile Fixes: 126185337, 126326421 Change-Id: Id28caebd36d0c66e83ee6ab4299f0ccb3bc6b488 (cherry picked from commit 7380bf8d3f680f32d027a7106e454e9134555edb) --- .../permission/model/AppPermissionGroup.java | 97 +++++++++++++------ .../permission/model/AppPermissions.java | 10 +- .../permission/service/BackupHelper.java | 4 +- .../PermissionControllerServiceImpl.java | 28 ++++-- .../handheld/ReviewPermissionsFragment.java | 2 +- 5 files changed, 96 insertions(+), 45 deletions(-) diff --git a/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java b/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java index f26d65740..b6a447c78 100644 --- a/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java +++ b/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java @@ -26,7 +26,6 @@ import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE; import static android.app.AppOpsManager.MODE_ALLOWED; import static android.app.AppOpsManager.MODE_FOREGROUND; import static android.app.AppOpsManager.MODE_IGNORED; -import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import android.app.ActivityManager; @@ -628,6 +627,25 @@ public final class AppPermissionGroup implements Comparable return grantRuntimePermissions(fixedByTheUser, null); } + /** + * Set mode of an app-op if needed. + * + * @param op The op to set + * @param uid The uid the app-op belongs top + * @param mode The new mode + * + * @return {@code true} iff app-op was changed + */ + private boolean setAppOpMode(@NonNull String op, int uid, int mode) { + int currentMode = mAppOps.unsafeCheckOpRaw(op, uid, mPackageInfo.packageName); + if (currentMode == mode) { + return false; + } + + mAppOps.setUidMode(op, uid, mode); + return true; + } + /** * Allow the app op for a permission/uid. * @@ -649,8 +667,12 @@ public final class AppPermissionGroup implements Comparable * * @param permission The permission which has an appOps that should be allowed * @param uid The uid of the process the app op if for + * + * @return {@code true} iff app-op was changed */ - private void allowAppOp(Permission permission, int uid) { + private boolean allowAppOp(Permission permission, int uid) { + boolean wasChanged = false; + if (permission.isBackgroundPermission()) { ArrayList foregroundPermissions = permission.getForegroundPermissions(); @@ -658,7 +680,7 @@ public final class AppPermissionGroup implements Comparable for (int i = 0; i < numForegroundPermissions; i++) { Permission foregroundPermission = foregroundPermissions.get(i); if (foregroundPermission.isAppOpAllowed()) { - mAppOps.setUidMode(foregroundPermission.getAppOp(), uid, MODE_ALLOWED); + wasChanged |= setAppOpMode(foregroundPermission.getAppOp(), uid, MODE_ALLOWED); } } } else { @@ -669,18 +691,20 @@ public final class AppPermissionGroup implements Comparable // The app requested a permission that has a background permission but it did // not request the background permission, hence it can never get background // access - mAppOps.setUidMode(permission.getAppOp(), uid, MODE_FOREGROUND); + wasChanged = setAppOpMode(permission.getAppOp(), uid, MODE_FOREGROUND); } else { if (backgroundPermission.isAppOpAllowed()) { - mAppOps.setUidMode(permission.getAppOp(), uid, MODE_ALLOWED); + wasChanged = setAppOpMode(permission.getAppOp(), uid, MODE_ALLOWED); } else { - mAppOps.setUidMode(permission.getAppOp(), uid, MODE_FOREGROUND); + wasChanged = setAppOpMode(permission.getAppOp(), uid, MODE_FOREGROUND); } } } else { - mAppOps.setUidMode(permission.getAppOp(), uid, MODE_ALLOWED); + wasChanged = setAppOpMode(permission.getAppOp(), uid, MODE_ALLOWED); } } + + return wasChanged; } /** @@ -846,8 +870,12 @@ public final class AppPermissionGroup implements Comparable * * @param permission The permission which has an appOps that should be disallowed * @param uid The uid of the process the app op if for + * + * @return {@code true} iff app-op was changed */ - private void disallowAppOp(Permission permission, int uid) { + private boolean disallowAppOp(Permission permission, int uid) { + boolean wasChanged = false; + if (permission.isBackgroundPermission()) { ArrayList foregroundPermissions = permission.getForegroundPermissions(); @@ -855,12 +883,15 @@ public final class AppPermissionGroup implements Comparable for (int i = 0; i < numForegroundPermissions; i++) { Permission foregroundPermission = foregroundPermissions.get(i); if (foregroundPermission.isAppOpAllowed()) { - mAppOps.setUidMode(foregroundPermission.getAppOp(), uid, MODE_FOREGROUND); + wasChanged |= setAppOpMode(foregroundPermission.getAppOp(), uid, + MODE_FOREGROUND); } } } else { - mAppOps.setUidMode(permission.getAppOp(), uid, MODE_IGNORED); + wasChanged = setAppOpMode(permission.getAppOp(), uid, MODE_IGNORED); } + + return wasChanged; } /** @@ -1134,7 +1165,9 @@ public final class AppPermissionGroup implements Comparable * app ops change. If this is set to {@code false} the * caller has to make sure to kill the app if needed. */ - public void persistChanges(boolean mayKillBecauseOfAppOpsChange) { + void persistChanges(boolean mayKillBecauseOfAppOpsChange) { + int uid = mPackageInfo.applicationInfo.uid; + int numPermissions = mPermissions.size(); boolean shouldKillApp = false; boolean shouldUpdateStorage = false; @@ -1147,8 +1180,13 @@ public final class AppPermissionGroup implements Comparable mPackageManager.grantRuntimePermission(mPackageInfo.packageName, permission.getName(), mUserHandle); } else { - mPackageManager.revokeRuntimePermission(mPackageInfo.packageName, - permission.getName(), mUserHandle); + boolean isCurrentlyGranted = mContext.checkPermission(permission.getName(), -1, + uid) == PERMISSION_GRANTED; + + if (isCurrentlyGranted) { + mPackageManager.revokeRuntimePermission(mPackageInfo.packageName, + permission.getName(), mUserHandle); + } } } @@ -1171,16 +1209,14 @@ public final class AppPermissionGroup implements Comparable if (permission.affectsAppOp()) { if (!permission.isSystemFixed()) { + // Enabling/Disabling an app op may put the app in a situation in which it has + // a handle to state it shouldn't have, so we have to kill the app. This matches + // the revoke runtime permission behavior. if (permission.isAppOpAllowed()) { - allowAppOp(permission, mPackageInfo.applicationInfo.uid); + shouldKillApp |= allowAppOp(permission, uid); } else { - disallowAppOp(permission, mPackageInfo.applicationInfo.uid); + shouldKillApp |= disallowAppOp(permission, uid); } - - // Enabling/Disabling an app op may put the app in a situation in which it has a - // handle to state it shouldn't have, so we have to kill the app. This matches - // the revoke runtime permission behavior. - shouldKillApp = true; } } @@ -1201,12 +1237,12 @@ public final class AppPermissionGroup implements Comparable // case, whenever any of the new split permissions are granted to an // app, we also grant them the legacy "Storage" permission. if (StorageManager.hasIsolatedStorage() && shouldUpdateStorage) { - boolean audioGranted = mPackageManager.checkPermission(READ_MEDIA_AUDIO, - mPackageInfo.packageName) == PERMISSION_GRANTED; - boolean videoGranted = mPackageManager.checkPermission(READ_MEDIA_VIDEO, - mPackageInfo.packageName) == PERMISSION_GRANTED; - boolean imagesGranted = mPackageManager.checkPermission(READ_MEDIA_IMAGES, - mPackageInfo.packageName) == PERMISSION_GRANTED; + boolean audioGranted = mContext.checkPermission(READ_MEDIA_AUDIO, + -1, uid) == PERMISSION_GRANTED; + boolean videoGranted = mContext.checkPermission(READ_MEDIA_VIDEO, + -1, uid) == PERMISSION_GRANTED; + boolean imagesGranted = mContext.checkPermission(READ_MEDIA_IMAGES, + -1, uid) == PERMISSION_GRANTED; if (!ArrayUtils.isEmpty(mPackageInfo.requestedPermissions)) { for (String permission : mPackageInfo.requestedPermissions) { @@ -1216,8 +1252,13 @@ public final class AppPermissionGroup implements Comparable mPackageManager.grantRuntimePermission(mPackageInfo.packageName, permission, mUserHandle); } else { - mPackageManager.revokeRuntimePermission(mPackageInfo.packageName, - permission, mUserHandle); + boolean isCurrentlyGranted = mContext.checkPermission(permission, -1, + uid) == PERMISSION_GRANTED; + + if (isCurrentlyGranted) { + mPackageManager.revokeRuntimePermission(mPackageInfo.packageName, + permission, mUserHandle); + } } } } diff --git a/src/com/android/packageinstaller/permission/model/AppPermissions.java b/src/com/android/packageinstaller/permission/model/AppPermissions.java index 125074f48..93e517a15 100644 --- a/src/com/android/packageinstaller/permission/model/AppPermissions.java +++ b/src/com/android/packageinstaller/permission/model/AppPermissions.java @@ -179,18 +179,22 @@ public final class AppPermissions { /** * If the changes to the permission groups were delayed, persist them now. + * + * @param mayKillBecauseOfAppOpsChange If the app may be killed if app ops change. If this is + * set to {@code false} the caller has to make sure to kill + * the app if needed. */ - public void persistChanges() { + public void persistChanges(boolean mayKillBecauseOfAppOpsChange) { if (mDelayChanges) { int numGroups = mGroups.size(); for (int i = 0; i < numGroups; i++) { AppPermissionGroup group = mGroups.get(i); - group.persistChanges(true); + group.persistChanges(mayKillBecauseOfAppOpsChange); AppPermissionGroup backgroundGroup = group.getBackgroundPermissions(); if (backgroundGroup != null) { - backgroundGroup.persistChanges(true); + backgroundGroup.persistChanges(mayKillBecauseOfAppOpsChange); } } } diff --git a/src/com/android/packageinstaller/permission/service/BackupHelper.java b/src/com/android/packageinstaller/permission/service/BackupHelper.java index ab0471624..d55d3f98a 100644 --- a/src/com/android/packageinstaller/permission/service/BackupHelper.java +++ b/src/com/android/packageinstaller/permission/service/BackupHelper.java @@ -17,7 +17,6 @@ package com.android.packageinstaller.permission.service; import static android.content.Context.MODE_PRIVATE; -import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED; import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; import static android.content.pm.PackageManager.GET_PERMISSIONS; @@ -53,7 +52,6 @@ import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; -import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.OutputStream; @@ -750,7 +748,7 @@ public class BackupHelper { } } - appPerms.persistChanges(); + appPerms.persistChanges(true); } } } diff --git a/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java b/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java index f04634ca5..09539d62e 100644 --- a/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java +++ b/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java @@ -286,7 +286,7 @@ public final class PermissionControllerServiceImpl extends PermissionControllerS if (!doDryRun) { int numChangedApps = appsWithRevokedPerms.size(); for (int i = 0; i < numChangedApps; i++) { - appsWithRevokedPerms.get(i).persistChanges(); + appsWithRevokedPerms.get(i).persistChanges(true); } } @@ -528,33 +528,41 @@ public final class PermissionControllerServiceImpl extends PermissionControllerS Collections.singletonList(unexpandedPermission), callerPkgInfo.applicationInfo.targetSdkVersion); + AppPermissions app = new AppPermissions(this, pkgInfo, false, null); + int numPerms = expandedPermissions.size(); for (int i = 0; i < numPerms; i++) { - String perm = expandedPermissions.get(i); - AppPermissionGroup group = AppPermissionGroup.create(this, pkgInfo, perm, true); + String permName = expandedPermissions.get(i); + AppPermissionGroup group = app.getGroupForPermission(permName); if (group == null || group.isSystemFixed()) { continue; } + Permission perm = group.getPermission(permName); + if (perm == null) { + continue; + } + switch (grantState) { case PERMISSION_GRANT_STATE_GRANTED: - group.getPermission(perm).setPolicyFixed(true); - group.grantRuntimePermissions(false, new String[]{perm}); + perm.setPolicyFixed(true); + group.grantRuntimePermissions(false, new String[]{permName}); break; case PERMISSION_GRANT_STATE_DENIED: - group.getPermission(perm).setPolicyFixed(true); - group.revokeRuntimePermissions(false, new String[]{perm}); + perm.setPolicyFixed(true); + group.revokeRuntimePermissions(false, new String[]{permName}); break; case PERMISSION_GRANT_STATE_DEFAULT: - group.getPermission(perm).setPolicyFixed(false); + perm.setPolicyFixed(false); break; default: return false; } - - group.persistChanges(!callerPackageName.equals(packageName)); } + app.persistChanges(grantState == PERMISSION_GRANT_STATE_DENIED + || !callerPackageName.equals(packageName)); + return true; } } diff --git a/src/com/android/packageinstaller/permission/ui/handheld/ReviewPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/ReviewPermissionsFragment.java index dd854b746..350448857 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/ReviewPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/ReviewPermissionsFragment.java @@ -211,7 +211,7 @@ public final class ReviewPermissionsFragment extends PreferenceFragmentCompat } } - mAppPermissions.persistChanges(); + mAppPermissions.persistChanges(true); } private void bindUi() { -- GitLab From f0e00daede46c075fb220a3775cfa3a711e3149e Mon Sep 17 00:00:00 2001 From: davidln Date: Tue, 26 Feb 2019 11:30:33 -0800 Subject: [PATCH 397/701] Update OWNERS for automotive changes in PermissionController. Bug: 122822231 Test: n/a Change-Id: If96f5a4a0f89df218285637e0912f1b8aa51f969 --- OWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OWNERS b/OWNERS index bda45f606..d79854830 100644 --- a/OWNERS +++ b/OWNERS @@ -7,4 +7,4 @@ eugenesusla@google.com # For automotive related changes stenning@google.com -rogerxue@google.com +davidln@google.com -- GitLab From 6ca901680ce8132d813c0c4dd145b1f48e934b72 Mon Sep 17 00:00:00 2001 From: Eugene Susla Date: Wed, 27 Feb 2019 15:21:24 -0800 Subject: [PATCH 398/701] Avoid aborting sms kill switch cleanup on unexpected exception There was a report of a kill switch not working as intended, which seems to be related to an unexpected exception happening during the cleanup: https://paste.googleplex.com/6587646319001600 It's difficult to pinpoint the exact root cause, as it's only reproducible on a userdebug device that is used as a personal one, so for now we should at least take a precaution to ensure any such failure's effect is localized to the problematic package/permission pair instead of bringing down the entire process. Bug: 124789865 Test: presubmit Change-Id: I9f31954623fc22ac363d6fb8b1ceea3f6407214c --- .../service/RoleControllerServiceImpl.java | 56 +++++++++++-------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/src/com/android/packageinstaller/role/service/RoleControllerServiceImpl.java b/src/com/android/packageinstaller/role/service/RoleControllerServiceImpl.java index bced5c601..0b42a7418 100644 --- a/src/com/android/packageinstaller/role/service/RoleControllerServiceImpl.java +++ b/src/com/android/packageinstaller/role/service/RoleControllerServiceImpl.java @@ -182,36 +182,44 @@ public class RoleControllerServiceImpl extends RoleControllerService { void onSmsKillSwitchToggled(boolean smsRestrictionEnabled, PackageInfo pkg, List permissions) { PackageManager pm = getPackageManager(); - int uid = pkg.applicationInfo.uid; //TODO multiuser support? + int uid = pkg.applicationInfo.uid; for (int i = 0, permissionsSize = permissions.size(); i < permissionsSize; i++) { PermissionInfo permission = permissions.get(i); - int permFlags = - pm.getPermissionFlags(permission.name, pkg.packageName, Process.myUserHandle()); - - if ((permFlags - & (PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT - | PackageManager.FLAG_PERMISSION_SYSTEM_FIXED)) != 0) { - continue; - } + try { + int permFlags = + pm.getPermissionFlags(permission.name, pkg.packageName, + Process.myUserHandle()); + + if ((permFlags + & (PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT + | PackageManager.FLAG_PERMISSION_SYSTEM_FIXED)) != 0) { + continue; + } - if ((permFlags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) { - pm.updatePermissionFlags(permission.name, pkg.packageName, - PackageManager.FLAG_PERMISSION_POLICY_FIXED, 0, Process.myUserHandle()); - } + if ((permFlags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) { + pm.updatePermissionFlags(permission.name, pkg.packageName, + PackageManager.FLAG_PERMISSION_POLICY_FIXED, 0, Process.myUserHandle()); + } - String appOp = AppOpsManager.permissionToOp(permission.name); - if (appOp != null) { - mAppOpsManager.setUidMode(appOp, uid, - smsRestrictionEnabled - ? AppOpsManager.MODE_DEFAULT - : AppOpsManager.MODE_ALLOWED); - } + String appOp = AppOpsManager.permissionToOp(permission.name); + if (appOp != null) { + mAppOpsManager.setUidMode(appOp, uid, + smsRestrictionEnabled + ? AppOpsManager.MODE_DEFAULT + : AppOpsManager.MODE_ALLOWED); + } - if (!smsRestrictionEnabled - && pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) { - pm.revokeRuntimePermission( - pkg.packageName, permission.name, Process.myUserHandle()); + if (!smsRestrictionEnabled + && pkg.applicationInfo.targetSdkVersion + > Build.VERSION_CODES.LOLLIPOP_MR1) { + pm.revokeRuntimePermission( + pkg.packageName, permission.name, Process.myUserHandle()); + } + } catch (Exception e) { + Log.e(LOG_TAG, "Unexpected exception while cleaning up state for package " + + pkg.packageName + " & " + permission.name, e); + continue; } } } -- GitLab From 8680ce47232b5f1374541df69a0d523e43ee812a Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Wed, 27 Feb 2019 08:41:54 -0800 Subject: [PATCH 399/701] Do not show usage information for custom permissions. Test: View these three screens for custom permissions. Change-Id: Ie3c55860beec1655a05dcd294c60eec718a0d18b --- .../ui/handheld/AppPermissionFragment.java | 32 +++++++++++-------- .../ui/handheld/AppPermissionsFragment.java | 26 ++++++++------- .../ui/handheld/PermissionAppsFragment.java | 3 ++ 3 files changed, 36 insertions(+), 25 deletions(-) diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java index 6e641814a..5bfc5dcdc 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java @@ -184,21 +184,25 @@ public class AppPermissionFragment extends SettingsWithButtonHeader { ((TextView) root.requireViewById(R.id.permission_message)).setText( context.getString(R.string.app_permission_header, mGroup.getLabel(), appLabel)); - String timeDiffStr = Utils.getRelativeLastUsageString(context, - PermissionUsages.loadLastGroupUsage(context, mGroup)); - if (timeDiffStr == null) { - ((TextView) root.requireViewById(R.id.usage_summary)).setText( - context.getString( - R.string.app_permission_footer_no_usages, - appLabel, - mGroup.getLabel().toString().toLowerCase())); + if (Utils.isModernPermissionGroup(mGroup.getName())) { + String timeDiffStr = Utils.getRelativeLastUsageString(context, + PermissionUsages.loadLastGroupUsage(context, mGroup)); + if (timeDiffStr == null) { + ((TextView) root.requireViewById(R.id.usage_summary)).setText( + context.getString( + R.string.app_permission_footer_no_usages, + appLabel, + mGroup.getLabel().toString().toLowerCase())); + } else { + ((TextView) root.requireViewById(R.id.usage_summary)).setText( + context.getString( + R.string.app_permission_footer_usage_summary, + appLabel, + mGroup.getLabel().toString().toLowerCase(), + timeDiffStr)); + } } else { - ((TextView) root.requireViewById(R.id.usage_summary)).setText( - context.getString( - R.string.app_permission_footer_usage_summary, - appLabel, - mGroup.getLabel().toString().toLowerCase(), - timeDiffStr)); + root.requireViewById(R.id.usage_summary).setVisibility(View.GONE); } root.requireViewById(R.id.usage_link).setOnClickListener((v) -> { diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java index bd6bf6ba9..6e4542c78 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java @@ -215,19 +215,23 @@ public final class AppPermissionsFragment extends SettingsWithButtonHeader { preference.setIcon(Utils.applyTint(context, icon, android.R.attr.colorControlNormal)); preference.setTitle(group.getFullLabel()); - String lastAccessStr = Utils.getAbsoluteLastUsageString(context, - PermissionUsages.loadLastGroupUsage(context, group)); - // STOPSHIP: Ignore {READ,WRITE}_EXTERNAL_STORAGE since they're going away. - if (lastAccessStr != null && !group.getLabel().equals("Storage")) { - preference.setSummary( - context.getString(R.string.app_permission_most_recent_summary, - lastAccessStr)); - } else { - preference.setGroupSummary(group); - if (preference.getSummary().length() == 0) { + if (Utils.isModernPermissionGroup(group.getName())) { + String lastAccessStr = Utils.getAbsoluteLastUsageString(context, + PermissionUsages.loadLastGroupUsage(context, group)); + // STOPSHIP: Ignore {READ,WRITE}_EXTERNAL_STORAGE since they're going away. + if (lastAccessStr != null && !group.getLabel().equals("Storage")) { preference.setSummary( - context.getString(R.string.app_permission_never_accessed_summary)); + context.getString(R.string.app_permission_most_recent_summary, + lastAccessStr)); + } else { + preference.setGroupSummary(group); + if (preference.getSummary().length() == 0) { + preference.setSummary( + context.getString(R.string.app_permission_never_accessed_summary)); + } } + } else { + preference.setGroupSummary(group); } if (isPlatform) { diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java index b736295d7..426c74d6f 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java @@ -363,6 +363,9 @@ public final class PermissionAppsFragment extends PermissionsFrameFragment imple private void setPreferenceSummary(AppPermissionGroup group, PermissionControlPreference pref, Context context) { + if (!Utils.isModernPermissionGroup(group.getName())) { + return; + } String lastAccessStr = Utils.getAbsoluteLastUsageString(context, PermissionUsages.loadLastGroupUsage(context, group)); // STOPSHIP: Ignore {READ,WRITE}_EXTERNAL_STORAGE since they're going away. -- GitLab From f2f46e6cfe3e07c8b30c088309978cd4333515c8 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Wed, 27 Feb 2019 09:27:05 -0800 Subject: [PATCH 400/701] Correctly handle empty usages. When PermissionUsages finds no usages (which happens at least for custom permissions), it does not call its callback, which causes UI screens to be waiting forever. This ensures it calls back and has AppPermissionUsage stop showing its loading bar. Test: View AppPermissionUsage with a custom permission. Test: Click around Permissions Hub a lot. Change-Id: I19e2c914b7f54c9ff11d6edd04f5ed98f3cde58f --- .../packageinstaller/permission/model/PermissionUsages.java | 3 --- .../permission/ui/handheld/AppPermissionUsageFragment.java | 1 + 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/com/android/packageinstaller/permission/model/PermissionUsages.java b/src/com/android/packageinstaller/permission/model/PermissionUsages.java index 08d19e9f5..c1ba9a862 100644 --- a/src/com/android/packageinstaller/permission/model/PermissionUsages.java +++ b/src/com/android/packageinstaller/permission/model/PermissionUsages.java @@ -119,9 +119,6 @@ public final class PermissionUsages implements LoaderCallbacks> loader, List usages) { - if (mUsages.equals(usages)) { - return; - } mUsages.clear(); mUsages.addAll(usages); if (mCallback != null) { diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java index 265e8b872..117134fa5 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java @@ -217,6 +217,7 @@ public class AppPermissionUsageFragment extends SettingsWithButtonHeader impleme // Add the permission usages. final List permissionUsages = mPermissionUsages.getUsages(); if (permissionUsages.isEmpty()) { + setLoading(false, true); return; } if (permissionUsages.size() > 1) { -- GitLab From 97c1e54e5766545c5439e6a4bb40ab078c0ce23c Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Thu, 28 Feb 2019 14:52:53 -0800 Subject: [PATCH 401/701] Convert usage preferences from nested LinearLayout to ConstraintLayout. The initial layout of the Permissions Hub has a very slow measure/layout phase. I believe this is due to having a large number of complicated layouts. The official documentation recommends replacing LinearLayouts with a layout_weight (which these did) with ConstraintLayouts. This commit makes that change. It should not change functionality at all. On my dev device, this seems to speed up the initial layout phase by 15-20%. Bug: 125332206 Test: Use systrace to time enabling "Show system apps". Test: Manually compare this to the old screen and they look about the same to me. Change-Id: I33849a6a1249822d1e13e204aeff3cc728a32762 --- res/layout/preference_usage.xml | 103 +++++++++++++++----------------- 1 file changed, 48 insertions(+), 55 deletions(-) diff --git a/res/layout/preference_usage.xml b/res/layout/preference_usage.xml index f42cf5548..3195623fd 100644 --- a/res/layout/preference_usage.xml +++ b/res/layout/preference_usage.xml @@ -15,10 +15,13 @@ ~ limitations under the License. --> - - + - - - - - - - - - - - - + android:gravity="start|center_vertical" + android:paddingEnd="16dp" + android:orientation="horizontal" + app:layout_constraintStart_toEndOf="@+id/image_frame_include" + app:layout_constraintBottom_toBottomOf="@android:id/title"/> - + - + - + + android:orientation="vertical" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="@+id/image_frame_include" + app:layout_constraintBottom_toBottomOf="@+id/image_frame_include"/> - + -- GitLab From 5f4e5290ea53ebe09ef90eef04b742a92f10a518 Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Thu, 28 Feb 2019 16:57:04 -0800 Subject: [PATCH 402/701] Add PermissionControllerService.isRoleVisible() for app info shortcut. The default app shortcut in app info inside Settings needs to know if a role is visible, and whether it is visible is controlled logic in PermissionController, hence add this API. Also fixed a bug where the visibility config is not properly retrieved. Bug: 124452117 Bug: 124457823 Test: manual Change-Id: I9888696dd36de91044c4fb9658f1c60c94d1801a --- .../service/PermissionControllerServiceImpl.java | 5 +++++ .../role/model/VisibilityMixin.java | 2 +- .../PermissionControllerServiceImplRoleMixin.java | 15 +++++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java b/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java index 09539d62e..7c0dd3d12 100644 --- a/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java +++ b/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java @@ -507,6 +507,11 @@ public final class PermissionControllerServiceImpl extends PermissionControllerS packageName, this); } + @Override + public boolean onIsRoleVisible(@NonNull String roleName) { + return PermissionControllerServiceImplRoleMixin.onIsRoleVisible(roleName, this); + } + @Override public boolean onSetRuntimePermissionGrantStateByDeviceAdmin(@NonNull String callerPackageName, @NonNull String packageName, @NonNull String unexpandedPermission, int grantState) { diff --git a/src/com/android/packageinstaller/role/model/VisibilityMixin.java b/src/com/android/packageinstaller/role/model/VisibilityMixin.java index 5096c3144..4ba928763 100644 --- a/src/com/android/packageinstaller/role/model/VisibilityMixin.java +++ b/src/com/android/packageinstaller/role/model/VisibilityMixin.java @@ -38,7 +38,7 @@ public class VisibilityMixin { */ public static boolean isVisible(@NonNull String resourceName, @NonNull Context context) { Resources resources = context.getResources(); - int resourceId = resources.getIdentifier(resourceName, "boolean", "android"); + int resourceId = resources.getIdentifier(resourceName, "bool", "android"); if (resourceId == 0) { Log.w(LOG_TAG, "Cannot find resource for visibility: " + resourceName); return true; diff --git a/src/com/android/packageinstaller/role/service/PermissionControllerServiceImplRoleMixin.java b/src/com/android/packageinstaller/role/service/PermissionControllerServiceImplRoleMixin.java index 29c7399fd..1914c4169 100644 --- a/src/com/android/packageinstaller/role/service/PermissionControllerServiceImplRoleMixin.java +++ b/src/com/android/packageinstaller/role/service/PermissionControllerServiceImplRoleMixin.java @@ -17,6 +17,7 @@ package com.android.packageinstaller.role.service; import android.content.Context; +import android.os.Process; import androidx.annotation.NonNull; @@ -46,4 +47,18 @@ public class PermissionControllerServiceImplRoleMixin { } return role.isPackageQualified(packageName, context); } + + /** + * @see android.permission.PermissionControllerService#onIsRoleVisible(String) + */ + public static boolean onIsRoleVisible(@NonNull String roleName, @NonNull Context context) { + Role role = Roles.get(context).get(roleName); + if (role == null) { + return false; + } + if (!role.isAvailable(context)) { + return false; + } + return role.isVisibleAsUser(Process.myUserHandle(), context); + } } -- GitLab From 61d4209984da6cdcee0c7e6ad9bc7be70cd2ee0e Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Thu, 28 Feb 2019 14:06:20 -0800 Subject: [PATCH 403/701] Allow passing a user handle to AppPermissionsFragment. Instead of always defaulting to the current user, allow passing a specific UserHandle to AppPermissionsFragment to control which user to show. Fixes: 126726013 Test: Click on normal and work profile app icon in SysUI and see correctly-labeled page. Test: Open AppPermissionsFragment from app info for normal and work apps and see the right one. Change-Id: I499a49d87c65d18cf4754841c055f57bbdfb3295 --- .../ui/ManagePermissionsActivity.java | 6 +++- .../ui/handheld/AppPermissionsFragment.java | 31 +++++++++++++------ 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/src/com/android/packageinstaller/permission/ui/ManagePermissionsActivity.java b/src/com/android/packageinstaller/permission/ui/ManagePermissionsActivity.java index 8ff73b31b..2b87507ec 100644 --- a/src/com/android/packageinstaller/permission/ui/ManagePermissionsActivity.java +++ b/src/com/android/packageinstaller/permission/ui/ManagePermissionsActivity.java @@ -118,8 +118,12 @@ public final class ManagePermissionsActivity extends FragmentActivity { androidXFragment = com.android.packageinstaller.permission.ui.handheld .AllAppPermissionsFragment.newInstance(packageName); } else { + UserHandle userHandle = getIntent().getParcelableExtra(Intent.EXTRA_USER); + if (userHandle == null) { + userHandle = UserHandle.of(UserHandle.myUserId()); + } androidXFragment = com.android.packageinstaller.permission.ui.handheld - .AppPermissionsFragment.newInstance(packageName); + .AppPermissionsFragment.newInstance(packageName, userHandle); } } } break; diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java index 6e4542c78..e9d98ae66 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java @@ -33,6 +33,7 @@ import android.view.MenuItem; import android.view.View; import android.widget.Toast; +import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; import androidx.preference.Preference; import androidx.preference.PreferenceCategory; @@ -64,13 +65,19 @@ public final class AppPermissionsFragment extends SettingsWithButtonHeader { private Collator mCollator; - public static AppPermissionsFragment newInstance(String packageName) { - return setPackageName(new AppPermissionsFragment(), packageName); + /** + * @return A new fragment + */ + public static AppPermissionsFragment newInstance(@NonNull String packageName, + @NonNull UserHandle userHandle) { + return setPackageNameAndUserHandle(new AppPermissionsFragment(), packageName, userHandle); } - private static T setPackageName(T fragment, String packageName) { + private static T setPackageNameAndUserHandle(@NonNull T fragment, + @NonNull String packageName, @NonNull UserHandle userHandle) { Bundle arguments = new Bundle(); arguments.putString(Intent.EXTRA_PACKAGE_NAME, packageName); + arguments.putParcelable(Intent.EXTRA_USER, userHandle); fragment.setArguments(arguments); return fragment; } @@ -86,8 +93,9 @@ public final class AppPermissionsFragment extends SettingsWithButtonHeader { } String packageName = getArguments().getString(Intent.EXTRA_PACKAGE_NAME); + UserHandle userHandle = getArguments().getParcelable(Intent.EXTRA_USER); Activity activity = getActivity(); - PackageInfo packageInfo = getPackageInfo(activity, packageName); + PackageInfo packageInfo = getPackageInfo(activity, packageName, userHandle); if (packageInfo == null) { Toast.makeText(activity, R.string.app_not_found_dlg_title, Toast.LENGTH_LONG).show(); activity.finish(); @@ -252,7 +260,9 @@ public final class AppPermissionsFragment extends SettingsWithButtonHeader { if (mExtraScreen != null) { extraPerms.setOnPreferenceClickListener(preference -> { AdditionalPermissionsFragment frag = new AdditionalPermissionsFragment(); - setPackageName(frag, getArguments().getString(Intent.EXTRA_PACKAGE_NAME)); + setPackageNameAndUserHandle(frag, + getArguments().getString(Intent.EXTRA_PACKAGE_NAME), + getArguments().getParcelable(Intent.EXTRA_USER)); frag.setTargetFragment(AppPermissionsFragment.this, 0); getFragmentManager().beginTransaction() .replace(android.R.id.content, frag) @@ -298,10 +308,12 @@ public final class AppPermissionsFragment extends SettingsWithButtonHeader { setLoading(false /* loading */, true /* animate */); } - private static PackageInfo getPackageInfo(Activity activity, String packageName) { + private static PackageInfo getPackageInfo(Activity activity, @NonNull String packageName, + @NonNull UserHandle userHandle) { try { - return activity.getPackageManager().getPackageInfo( - packageName, PackageManager.GET_PERMISSIONS); + return activity.createPackageContextAsUser(packageName, 0, + userHandle).getPackageManager().getPackageInfo(packageName, + PackageManager.GET_PERMISSIONS); } catch (PackageManager.NameNotFoundException e) { Log.i(LOG_TAG, "No package:" + activity.getCallingPackage(), e); return null; @@ -327,7 +339,8 @@ public final class AppPermissionsFragment extends SettingsWithButtonHeader { public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); String packageName = getArguments().getString(Intent.EXTRA_PACKAGE_NAME); - bindUi(this, getPackageInfo(getActivity(), packageName)); + UserHandle userHandle = getArguments().getParcelable(Intent.EXTRA_USER); + bindUi(this, getPackageInfo(getActivity(), packageName, userHandle)); } @Override -- GitLab From 45f17438550439b2e3180595d2bbc0af7f69e4c6 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Fri, 1 Mar 2019 13:39:55 -0800 Subject: [PATCH 404/701] Increase string char limit. This was requested by translators. Bug: 126266231 Test: Verify that it looks good with 42 characters. Change-Id: Ia0681843b3896a3b5137490d460dd5ae73fe0aa4 --- res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index ae1f41c0e..b6cef80b7 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -133,7 +133,7 @@ Recent usage - + View Permissions Dashboard -- GitLab From 8b24aab47596662741b648c510eb77d09d06aed9 Mon Sep 17 00:00:00 2001 From: Svet Ganov Date: Mon, 18 Feb 2019 16:24:44 -0800 Subject: [PATCH 405/701] Slice and dice app ops - PermissionController Update the code to only pull and query the trsuted portion of the last/historical app op data. Test: manual bug:111061782 Change-Id: I939db3d36fd546af2b0adfd4d9e657e0b195f09f --- .../permission/model/AppPermissionUsage.java | 21 ++++++++++++------- .../permission/model/PermissionUsages.java | 1 + .../service/LocationAccessCheck.java | 3 ++- .../ReviewAccessibilityServicesActivity.java | 3 ++- .../permission/utils/Utils.java | 1 + 5 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/com/android/packageinstaller/permission/model/AppPermissionUsage.java b/src/com/android/packageinstaller/permission/model/AppPermissionUsage.java index dc94a83ca..b69392c5d 100644 --- a/src/com/android/packageinstaller/permission/model/AppPermissionUsage.java +++ b/src/com/android/packageinstaller/permission/model/AppPermissionUsage.java @@ -16,6 +16,7 @@ package com.android.packageinstaller.permission.model; +import android.app.AppOpsManager; import android.app.AppOpsManager.HistoricalOp; import android.app.AppOpsManager.HistoricalPackageOps; import android.app.AppOpsManager.OpEntry; @@ -25,6 +26,8 @@ import android.app.AppOpsManager.PackageOps; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.packageinstaller.permission.model.PermissionApps.PermissionApp; +import com.android.packageinstaller.permission.utils.Utils; + import java.util.ArrayList; import java.util.List; import java.util.function.Function; @@ -115,7 +118,8 @@ public final class AppPermissionUsage { for (int j = 0; j < opCount; j++) { final OpEntry op = ops.get(j); if (op.getOpStr().equals(opName)) { - lastAccessTime = Math.max(lastAccessTime, op.getLastAccessTime()); + lastAccessTime = Math.max(lastAccessTime, + op.getLastAccessTime(AppOpsManager.OP_FLAGS_ALL_TRUSTED)); } } } @@ -127,14 +131,16 @@ public final class AppPermissionUsage { if (mHistoricalUsage == null) { return 0; } - return extractAggregate(HistoricalOp::getForegroundAccessCount); + return extractAggregate((HistoricalOp op) + -> op.getForegroundAccessCount(AppOpsManager.OP_FLAGS_ALL_TRUSTED)); } public long getBackgroundAccessCount() { if (mHistoricalUsage == null) { return 0; } - return extractAggregate(HistoricalOp::getBackgroundAccessCount); + return extractAggregate((HistoricalOp op) + -> op.getBackgroundAccessCount(AppOpsManager.OP_FLAGS_ALL_TRUSTED)); } public long getAccessCount() { @@ -142,7 +148,8 @@ public final class AppPermissionUsage { return 0; } return extractAggregate((HistoricalOp op) -> - op.getForegroundAccessCount() + op.getBackgroundAccessCount() + op.getForegroundAccessCount(AppOpsManager.OP_FLAGS_ALL_TRUSTED) + + op.getBackgroundAccessCount(AppOpsManager.OP_FLAGS_ALL_TRUSTED) ); } @@ -151,7 +158,8 @@ public final class AppPermissionUsage { return 0; } return extractAggregate((HistoricalOp op) -> - op.getForegroundAccessDuration() + op.getBackgroundAccessDuration() + op.getForegroundAccessDuration(AppOpsManager.OP_FLAGS_ALL_TRUSTED) + + op.getBackgroundAccessDuration(AppOpsManager.OP_FLAGS_ALL_TRUSTED) ); } @@ -200,8 +208,7 @@ public final class AppPermissionUsage { return this; } - public @NonNull - AppPermissionUsage build() { + public @NonNull AppPermissionUsage build() { if (mGroups.isEmpty()) { throw new IllegalStateException("mGroups cannot be empty."); } diff --git a/src/com/android/packageinstaller/permission/model/PermissionUsages.java b/src/com/android/packageinstaller/permission/model/PermissionUsages.java index c1ba9a862..71248392b 100644 --- a/src/com/android/packageinstaller/permission/model/PermissionUsages.java +++ b/src/com/android/packageinstaller/permission/model/PermissionUsages.java @@ -292,6 +292,7 @@ public final class PermissionUsages implements LoaderCallbacks(opNames)) + .setFlags(AppOpsManager.OP_FLAGS_ALL_TRUSTED) .build(); appOpsManager.getHistoricalOps(request, Runnable::run, (HistoricalOps ops) -> { diff --git a/src/com/android/packageinstaller/permission/service/LocationAccessCheck.java b/src/com/android/packageinstaller/permission/service/LocationAccessCheck.java index 11bf295fc..08a20c7b8 100644 --- a/src/com/android/packageinstaller/permission/service/LocationAccessCheck.java +++ b/src/com/android/packageinstaller/permission/service/LocationAccessCheck.java @@ -96,6 +96,7 @@ import androidx.core.util.Preconditions; import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.ui.AppPermissionActivity; import com.android.packageinstaller.permission.utils.CollectionUtils; +import com.android.packageinstaller.permission.utils.Utils; import com.android.permissioncontroller.R; import java.io.BufferedReader; @@ -509,7 +510,7 @@ public class LocationAccessCheck { for (int opNum = 0; opNum < numOps; opNum++) { AppOpsManager.HistoricalOp op = ops.getOpAt(opNum); - if (op.getBackgroundAccessCount() > 0) { + if (op.getBackgroundAccessCount(AppOpsManager.OP_FLAGS_ALL_TRUSTED) > 0) { pkgsWithLocationAccess.add(userPkg); break; diff --git a/src/com/android/packageinstaller/permission/ui/ReviewAccessibilityServicesActivity.java b/src/com/android/packageinstaller/permission/ui/ReviewAccessibilityServicesActivity.java index 61df3f7f5..c2bb9bb9d 100644 --- a/src/com/android/packageinstaller/permission/ui/ReviewAccessibilityServicesActivity.java +++ b/src/com/android/packageinstaller/permission/ui/ReviewAccessibilityServicesActivity.java @@ -148,7 +148,8 @@ public final class ReviewAccessibilityServicesActivity extends FragmentActivity int numOps = pkgOp.getOps().size(); for (int opNum = 0; opNum < numOps; opNum++) { AppOpsManager.OpEntry op = pkgOp.getOps().get(opNum); - lastAccessTime = Math.max(lastAccessTime, op.getLastAccessTime()); + lastAccessTime = Math.max(lastAccessTime, + op.getLastAccessTime(AppOpsManager.OP_FLAGS_ALL_TRUSTED)); } } return lastAccessTime; diff --git a/src/com/android/packageinstaller/permission/utils/Utils.java b/src/com/android/packageinstaller/permission/utils/Utils.java index d2a8735d2..307255f8b 100644 --- a/src/com/android/packageinstaller/permission/utils/Utils.java +++ b/src/com/android/packageinstaller/permission/utils/Utils.java @@ -31,6 +31,7 @@ import static android.Manifest.permission_group.SMS; import static android.Manifest.permission_group.STORAGE; import android.Manifest; +import android.app.AppOpsManager; import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; -- GitLab From 045400e82b0a1ef3632ce0fbdc4111d1299a3911 Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Fri, 1 Mar 2019 15:23:19 -0800 Subject: [PATCH 406/701] Test Perm grant/managment UI as postsubmit Too flaky on cloud devices for presubmit Test: atest --test-mapping packages/apps/PermissionController/src/com/android/packageinstaller/permission/ui:postsubmit Bug: 126264742 Change-Id: Iac35692d708a48e5de7932b073634419e8355882 --- .../packageinstaller/permission/ui/TEST_MAPPING | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/com/android/packageinstaller/permission/ui/TEST_MAPPING diff --git a/src/com/android/packageinstaller/permission/ui/TEST_MAPPING b/src/com/android/packageinstaller/permission/ui/TEST_MAPPING new file mode 100644 index 000000000..08c33b46f --- /dev/null +++ b/src/com/android/packageinstaller/permission/ui/TEST_MAPPING @@ -0,0 +1,12 @@ +{ + "postsubmit": [ + { + "name": "CtsAppSecurityHostTestCases", + "options": [ + { + "include-filter": "android.appsecurity.cts.PermissionsHostTest" + } + ] + } + ] +} \ No newline at end of file -- GitLab From e8093f7f6283d99ab145bd0627103dfe5385e3a9 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Sat, 2 Mar 2019 03:51:33 -0800 Subject: [PATCH 407/701] Import translations. DO NOT MERGE Change-Id: Ie5e0eff86fee3ffdc3031fe8a5698b1a633f45b7 Auto-generated-cl: translation import --- res/values-af/strings.xml | 24 ++++++++++++++--- res/values-am/strings.xml | 24 ++++++++++++++--- res/values-ar/strings.xml | 40 +++++++++++++++++++++++++--- res/values-as/strings.xml | 45 +++++++++++++++++++------------- res/values-az/strings.xml | 24 ++++++++++++++--- res/values-b+sr+Latn/strings.xml | 28 +++++++++++++++++--- res/values-be/strings.xml | 32 ++++++++++++++++++++--- res/values-bg/strings.xml | 24 ++++++++++++++--- res/values-bn/strings.xml | 24 ++++++++++++++--- res/values-bs/strings.xml | 28 +++++++++++++++++--- res/values-ca/strings.xml | 26 ++++++++++++++---- res/values-cs/strings.xml | 32 ++++++++++++++++++++--- res/values-da/strings.xml | 24 ++++++++++++++--- res/values-de/strings.xml | 30 ++++++++++++++++----- res/values-el/strings.xml | 24 ++++++++++++++--- res/values-en-rAU/strings.xml | 24 ++++++++++++++--- res/values-en-rCA/strings.xml | 24 ++++++++++++++--- res/values-en-rGB/strings.xml | 24 ++++++++++++++--- res/values-en-rIN/strings.xml | 24 ++++++++++++++--- res/values-en-rXC/strings.xml | 24 ++++++++++++++--- res/values-es-rUS/strings.xml | 24 ++++++++++++++--- res/values-es/strings.xml | 24 ++++++++++++++--- res/values-et/strings.xml | 24 ++++++++++++++--- res/values-eu/strings.xml | 24 ++++++++++++++--- res/values-fa/strings.xml | 24 ++++++++++++++--- res/values-fi/strings.xml | 24 ++++++++++++++--- res/values-fr-rCA/strings.xml | 24 ++++++++++++++--- res/values-fr/strings.xml | 24 ++++++++++++++--- res/values-gl/strings.xml | 24 ++++++++++++++--- res/values-gu/strings.xml | 24 ++++++++++++++--- res/values-hi/strings.xml | 37 +++++++++++++------------- res/values-hr/strings.xml | 28 +++++++++++++++++--- res/values-hu/strings.xml | 24 ++++++++++++++--- res/values-hy/strings.xml | 24 ++++++++++++++--- res/values-in/strings.xml | 24 ++++++++++++++--- res/values-is/strings.xml | 24 ++++++++++++++--- res/values-it/strings.xml | 24 ++++++++++++++--- res/values-iw/strings.xml | 32 ++++++++++++++++++++--- res/values-ja/strings.xml | 24 ++++++++++++++--- res/values-ka/strings.xml | 24 ++++++++++++++--- res/values-kk/strings.xml | 45 +++++++++++++++++++------------- res/values-km/strings.xml | 45 +++++++++++++++++++------------- res/values-kn/strings.xml | 24 ++++++++++++++--- res/values-ko/strings.xml | 24 ++++++++++++++--- res/values-ky/strings.xml | 45 +++++++++++++++++++------------- res/values-lo/strings.xml | 24 ++++++++++++++--- res/values-lt/strings.xml | 32 ++++++++++++++++++++--- res/values-lv/strings.xml | 28 +++++++++++++++++--- res/values-mk/strings.xml | 24 ++++++++++++++--- res/values-ml/strings.xml | 45 +++++++++++++++++++------------- res/values-mn/strings.xml | 24 ++++++++++++++--- res/values-mr/strings.xml | 45 +++++++++++++++++++------------- res/values-ms/strings.xml | 24 ++++++++++++++--- res/values-my/strings.xml | 24 ++++++++++++++--- res/values-nb/strings.xml | 24 ++++++++++++++--- res/values-ne/strings.xml | 24 ++++++++++++++--- res/values-nl/strings.xml | 24 ++++++++++++++--- res/values-or/strings.xml | 37 +++++++++++++------------- res/values-pa/strings.xml | 45 +++++++++++++++++++------------- res/values-pl/strings.xml | 32 ++++++++++++++++++++--- res/values-pt-rBR/strings.xml | 24 ++++++++++++++--- res/values-pt-rPT/strings.xml | 24 ++++++++++++++--- res/values-pt/strings.xml | 24 ++++++++++++++--- res/values-ro/strings.xml | 28 +++++++++++++++++--- res/values-ru/strings.xml | 32 ++++++++++++++++++++--- res/values-si/strings.xml | 24 ++++++++++++++--- res/values-sk/strings.xml | 36 ++++++++++++++++++++----- res/values-sl/strings.xml | 32 ++++++++++++++++++++--- res/values-sq/strings.xml | 24 ++++++++++++++--- res/values-sr/strings.xml | 28 +++++++++++++++++--- res/values-sv/strings.xml | 24 ++++++++++++++--- res/values-sw/strings.xml | 24 ++++++++++++++--- res/values-ta/strings.xml | 37 +++++++++++++------------- res/values-te/strings.xml | 45 +++++++++++++++++++------------- res/values-th/strings.xml | 45 +++++++++++++++++++------------- res/values-tl/strings.xml | 24 ++++++++++++++--- res/values-tr/strings.xml | 24 ++++++++++++++--- res/values-uk/strings.xml | 32 ++++++++++++++++++++--- res/values-ur/strings.xml | 24 ++++++++++++++--- res/values-uz/strings.xml | 28 +++++++++++++++----- res/values-vi/strings.xml | 24 ++++++++++++++--- res/values-zh-rCN/strings.xml | 45 +++++++++++++++++++------------- res/values-zh-rHK/strings.xml | 45 +++++++++++++++++++------------- res/values-zh-rTW/strings.xml | 24 ++++++++++++++--- res/values-zu/strings.xml | 24 ++++++++++++++--- 85 files changed, 1894 insertions(+), 544 deletions(-) diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml index 8a75764a3..557c7cffd 100644 --- a/res/values-af/strings.xml +++ b/res/values-af/strings.xml @@ -39,6 +39,7 @@ "Laat net toe wanneer die program gebruik word" "Programme" "Programtoestemmings" + "Toestemmingbestuurder" "Moenie weer vra nie" "Geen toestemmings nie" "Bykomende toestemmings" @@ -51,7 +52,7 @@ "voer \'n onbekende handeling uit" "%1$d van %2$d programme toegelaat" "Onlangse gebruik" - "Bekyk besonderhede" + "Bekyk toestemmingkontroleskerm" "Wys stelsel" "Versteek stelsel" "Geen programme nie" @@ -90,9 +91,23 @@ "Huidige toestemmings" "Voer tans program uit …" "Onbekend" - "Toestemmingsgebruik" - "Laaste toegang: %1$s\n%2$s keer ingegaan" - "Laaste toegang: %1$s\n%2$s keer ingegaan (%3$s in agtergrond)" + "Kontroleskerm" + + Jongste gebruik: %1$s\n%2$s keer gebruik + Jongste gebruik: %1$s\n%2$s keer gebruik + + + Jongste gebruik: %1$s\n%2$s keer gebruik (%3$s keer op agtergrond) + Jongste gebruik: %1$s\n%2$s keer gebruik (%3$s keer op agtergrond) + + + Jongste gebruik: %1$s\n%2$s keer gebruik\nTydsduur: %3$s + Jongste gebruik: %1$s\n%2$s keer gebruik\nTydsduur: %3$s + + + Jongste gebruik: %1$s\n%2$s keer gebruik (%3$s keer op agtergrond)\nTydsduur: %3$s + Jongste gebruik: %1$s\n%2$s keer gebruik (%3$s keer op agtergrond)\nTydsduur: %3$s + "Enige toestemming" "Enige tyd" "Afgelope 7 dae" @@ -135,6 +150,7 @@ "%1$s het nie toegang gekry tot jou %2$s nie." "Bekyk gedetailleerde toestemmingsgebruik" "Jongste toegang: %1$s" + "Nooit gebruik nie" "Toegelaat" "Net toegelaat wanneer dit gebruik word" "Geweier" diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml index 1beffa73a..b300a06c2 100644 --- a/res/values-am/strings.xml +++ b/res/values-am/strings.xml @@ -39,6 +39,7 @@ "መተግበሪያው ጥቅም ላይ እያለ ብቻ ፍቀድ" "መተግበሪያዎች" "የመተግበሪያ ፈቃዶች" + "የፈቃድ አቀናባሪ" "ዳግም አትጠይቅ" "ምንም ፈቃዶች የሉም" "ተጨማሪ ፈቃዶች" @@ -51,7 +52,7 @@ "ያልታወቀ እርምጃ ያከናውናል" "%1$d%2$d መተግበሪያዎች ተፈቅዶላቸዋል" "የቅርብ ጊዜ አጠቃቀም" - "ዝርዝሮችን አሳይ" + "የፈቃዶች ዳሽቦርድን ይመልከቱ" "ሥርዓት አሳይ" "ሥርዓትን ደብቅ" "ምንም መተግበሪያዎች የሉም" @@ -90,9 +91,23 @@ "የአሁኖቹ ፍቃዶች" "መተግበሪያን በማዘጋጀት ላይ…" "ያልታወቀ" - "የፈቃዶች አጠቃቀም" - "ለመጨረሻ ጊዜ የተደረሰው፦ %1$s\n%2$s መዳረሻዎች" - "ለመጨረሻ ጊዜ የተደረሰው፦ %1$s\n%2$s መዳረሻዎች (%3$s በበስተጀርባ)" + "ዳሽቦርድ" + + የመጨረሻ መዳረሻ፦ %1$s\n%2$s መዳረሻዎች + የመጨረሻ መዳረሻ፦ %1$s\n%2$s መዳረሻዎች + + + የመጨረሻ መዳረሻ፦ %1$s\n%2$s መዳረሻዎች (በበስተጀርባ ውስጥ %3$s) + የመጨረሻ መዳረሻ፦ %1$s\n%2$s መዳረሻዎች (በበስተጀርባ ውስጥ %3$s) + + + የመጨረሻ መዳረሻ፦ %1$s\n%2$s መዳረሻዎች\nየጊዜ ቆይታ፦ %3$s + የመጨረሻ መዳረሻ፦ %1$s\n%2$s መዳረሻዎች\nየጊዜ ቆይታ፦ %3$s + + + የመጨረሻ መዳረሻ፦ %1$s\n%2$s መዳረሻዎች (በበስተጀርባ ላይ %3$s)\nየጊዜ ቆይታ፦ %3$s + የመጨረሻ መዳረሻ፦ %1$s\n%2$s መዳረሻዎች (በበስተጀርባ ላይ %3$s)\nየጊዜ ቆይታ፦ %3$s + "ማናቸውም ፈቃድ" "በማንኛውም ጊዜ" "ባለፉት 7 ቀኖች" @@ -135,6 +150,7 @@ "%1$s የእርስዎን %2$s አልደረሰበትም።" "ዝርዝር የፈቃዶች አጠቃቀምን ይመልከቱ" "የመጨረሻ መዳረሻ፦ %1$s" + "ተደርሶ አያውቅም" "ይፈቀዳል" "ስራ ላይ ሲውል ብቻ የሚፈቀድ" "ውድቅ ተደርጓል" diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml index 106c9bcae..71b1022e7 100644 --- a/res/values-ar/strings.xml +++ b/res/values-ar/strings.xml @@ -39,6 +39,7 @@ "السماح فقط أثناء استخدام التطبيق" "تطبيقات" "أذونات التطبيق" + "مدير الأذونات" "عدم السؤال مجدّدًا" "ليس هناك أيّ أذونات." "أذونات إضافية" @@ -55,7 +56,7 @@ "تنفيذ إجراء غير معروف" "تمّ السماح لـ %1$d من أصل %2$d تطبيق" "الاستخدام الأخير" - "عرض التفاصيل" + "عرض لوحة التحكم في الأذونات" "عرض النظام" "إخفاء النظام" "ليس هناك أيّ تطبيقات." @@ -94,9 +95,39 @@ "الأذونات الحالية" "جارٍ الطرح المرحلي للتطبيق…" "غير معروف" - "استخدام الأذونات" - "آخر إذن وصول: %1$s\n%2$s إذن وصول" - "آخر إذن وصول: %1$s\n%2$s إذن وصول (%3$s في الخلفية)" + "لوحة التحكّم" + + آخر إذن وصول: %1$s\n%2$s إذن وصول + آخر إذن وصول: %1$s\nإذنا وصول (%2$s) + آخر إذن وصول: %1$s\n%2$s أذونات وصول + آخر إذن وصول: %1$s\n%2$s إذن وصول + آخر إذن وصول: %1$s\n%2$s إذن وصول + آخر إذن وصول: %1$s\n%2$s إذن وصول + + + آخر إذن وصول: %1$s\n%2$s إذن وصول (%3$s في الخلفية) + آخر إذن وصول: %1$s\nإذنا وصول (%2$s) (%3$s في الخلفية) + آخر إذن وصول: %1$s\n%2$s أذونات وصول (%3$s في الخلفية) + آخر إذن وصول: %1$s\n%2$s إذن وصول (%3$s في الخلفية) + آخر إذن وصول: %1$s\n%2$s إذن وصول (%3$s في الخلفية) + آخر إذن وصول: %1$s\n%2$s إذن وصول (%3$s في الخلفية) + + + آخر إذن وصول: %1$s\n%2$s إذن وصول\nالمدة: %3$s + آخر إذن وصول: %1$s\nإذنا وصول (%2$s)\nالمدة: %3$s + آخر إذن وصول: %1$s\n%2$s أذونات وصول\nالمدة: %3$s + آخر إذن وصول: %1$s\n%2$s إذن وصول\nالمدة: %3$s + آخر إذن وصول: %1$s\n%2$s إذن وصول\nالمدة: %3$s + آخر إذن وصول: %1$s\n%2$s إذن وصول\nالمدة: %3$s + + + آخر إذن وصول: %1$s\n%2$s إذن وصول (%3$s في الخلفية)\nالمدة: %3$s + آخر إذن وصول: %1$s\nإذنا وصول (%2$s) (%3$s في الخلفية)\nالمدة: %3$s + آخر إذن وصول: %1$s\n%2$s أذونات وصول (%3$s في الخلفية)\nالمدة: %3$s + آخر إذن وصول: %1$s\n%2$s إذن وصول (%3$s في الخلفية)\nالمدة: %3$s + آخر إذن وصول: %1$s\n%2$s إذن وصول (%3$s في الخلفية)\nالمدة: %3$s + آخر إذن وصول: %1$s\n%2$s إذن وصول (%3$s في الخلفية)\nالمدة: %3$s + "أيّ إذن" "أي وقت" "آخر 7 أيام" @@ -139,6 +170,7 @@ "لم يحصل تطبيق %1$s على إذن %2$s." "عرض تفاصيل استخدام الأذونات" "آخر إذن وصول: %1$s" + "لم يتم الوصول مطلقًا." "التطبيقات أو الأذونات المسموح بها" "السماح فقط أثناء الاستخدام" "التطبيقات أو الأذونات المرفوضة" diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml index a9cc502e9..dba1de5d1 100644 --- a/res/values-as/strings.xml +++ b/res/values-as/strings.xml @@ -39,6 +39,7 @@ "কেৱল এপটো ব্যৱহাৰ হৈ থকা সময়ত অনুমতি দিয়ক" "এপ্" "এপ্‌ৰ অনুমতি" + "অনুমতি পৰিচালক" "পুনৰাই নুসুধিব" "কোনো অনুমতি নাই" "অতিৰিক্ত অনুমতি" @@ -51,7 +52,7 @@ "অজ্ঞাত কাৰ্য কৰিব পাৰে" "%2$dৰ ভিতৰত %1$dটা এপক অনুমতি দিয়া হৈছে" "শেহতীয়া ব্যৱহাৰৰ তথ্য" - "সবিশেষ চাওক" + "অনুমতিৰ ডেশ্বব’ৰ্ড চাওক" "ছিষ্টেম দেখুৱাওক" "ছিষ্টেম লুকুৱাওক" "কোনো এপে এই অনুমতি বিচৰা নাই" @@ -90,9 +91,23 @@ "সাম্প্ৰতিক অনুমতি" "এপৰ অন্তিম পর্যায়ৰ পৰীক্ষণ চলি আছে…" "অজ্ঞাত" - "অনুমতিৰ ব্যৱহাৰ" - "শেহতীয়া এক্সেছৰ সংখ্যা: %1$s\n%2$sটা এক্সেছ" - "শেহতীয়া এক্সেছৰ সংখ্যা: %1$s\n%2$sটা এক্সেছ (%3$sটা নেপথ্যত)" + "ডেশ্বব’ৰ্ড" + + শেহতীয়া এক্সেছৰ সংখ্যা: %1$s\n%2$sটা এক্সেছ + শেহতীয়া এক্সেছৰ সংখ্যা: %1$s\n%2$sটা এক্সেছ + + + শেহতীয়া এক্সেছৰ সংখ্যা: %1$s\n%2$sটা এক্সেছ (নেপথ্যত %3$sটা) + শেহতীয়া এক্সেছৰ সংখ্যা: %1$s\n%2$sটা এক্সেছ (নেপথ্যত %3$sটা) + + + শেহতীয়া এক্সেছৰ সংখ্যা: %1$s\n%2$sটা এক্সেছ\nদৈৰ্ঘ্য: %3$s + শেহতীয়া এক্সেছৰ সংখ্যা: %1$s\n%2$sটা এক্সেছ\nদৈৰ্ঘ্য: %3$s + + + শেহতীয়া এক্সেছৰ সংখ্যা: %1$s\n%2$sটা এক্সেছ (নেপথ্যত %3$sটা)\nদৈৰ্ঘ্য: %3$s + শেহতীয়া এক্সেছৰ সংখ্যা: %1$s\n%2$sটা এক্সেছ (নেপথ্যত %3$sটা)\nদৈৰ্ঘ্য: %3$s + "যিকোনো অনুমতি" "যিকোনো সময়ত" "যোৱা ৭ দিনত" @@ -135,6 +150,7 @@ "%1$sএ আপোনাৰ %2$s এক্সেছ কৰা নাই।" "অনুমতিৰ ব্যৱহাৰৰ সবিশেষ চাওক" "অন্তিমবাৰ এক্সেছ কৰা হৈছিল: %1$s" + "কেতিয়াও এক্সেছ কৰা নাই" "অনুমতি দিয়া হৈছে" "কেৱল ব্যৱহাৰ হৈ থকা সময়ত অনুমতি দিয়া হয়" "অস্বীকাৰ কৰা হৈছে" @@ -168,16 +184,11 @@ "খোলক" "আনইনষ্টল কৰক" "বলেৰে বন্ধ কৰক" - - - - - - - - - - + "ছেটিংসমূহ" + "%sএ আপোনাৰ ডিভাইচটো সম্পূৰ্ণভাৱে এক্সেছ কৰিব পাৰে" + "%s সাধ্য সুবিধাসমূহে আপোনাৰ ডিভাইচটো সম্পূৰ্ণভাৱে এক্সেছ কৰিব পাৰে" + "%sএ আপোনাৰ স্ক্ৰীণ, কাৰ্য আৰু ইনপুট চাব পাৰে, কাৰ্য সম্পন্ন কৰিব পাৰে আৰু ডিছপ্লে’ নিয়ন্ত্ৰণ কৰিব পাৰে।" + "এই সেৱাবোৰে আপোনাৰ স্ক্ৰীণ, কাৰ্য আৰু ইনপুট চাব পাৰে, কাৰ্য সম্পন্ন কৰিব পাৰে আৰু ডিছপ্লে’ নিয়ন্ত্ৰণ কৰিব পাৰে।" "ডিফ’ল্ট এপ্" "কোনো ডিফ’ল্ট এপ্ নাই" "কৰ্মস্থানৰ বাবে ডিফ’ল্ট" @@ -199,11 +210,9 @@ "কল স্ক্ৰীণ কৰা এপ্" "কল সহযোগী এপ্" "গাড়ীৰ প্ৰজেকশ্বন এপ্‌" - - + "কৰ্মস্থানৰ প্ৰ’ফাইল সমৰ্থন নকৰে" "টোকা: যদি আপুনি আপোনাৰ ডিভাইচটো ৰিষ্টাৰ্ট কৰে আৰু আপোনাৰ এটা স্ক্ৰীণ লক ছেট কৰি থোৱা আছে, তেন্তে এই এপটো আপুনি ডিভাইচটো আনলক নকৰালৈকে আৰম্ভ নহ’ব।" - - + "এই সহায়কটোৱে আপোনাৰ ছিষ্টেমত ব্যৱহৃত হৈ থকা এপ্‌সমূহৰ বিষয়ে তথ্য পঢ়িব পাৰিব। সেই তথ্যসমূহৰ ভিতৰত আপোনাৰ স্ক্ৰীণত দেখা পোৱা বা এপে চাব পৰা তথ্যসমূহ অন্তৰ্ভুক্ত।" "ডিবাগ ডেটা শ্বেয়াৰ কৰক" "ডিবাগৰ সবিশেষ ডেটা শ্বেয়াৰ কৰিবনে?" "%1$sএ ডিবাগ তথ্য আপল’ড কৰিব বিচাৰিছে।" diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml index 85d9a9a9b..536c2da19 100644 --- a/res/values-az/strings.xml +++ b/res/values-az/strings.xml @@ -39,6 +39,7 @@ "Yalnız tətbiqin istifadəsi zamanı icazə verin" "Tətbiq" "Tətbiq icazələri" + "İcazə meneceri" "Bir daha soruşmayın" "İcazə yoxdur" "Əlavə icazələr" @@ -51,7 +52,7 @@ "naməlum əməliyyat etmək" "%2$d tətbiqdən %1$d ədədi icazəlidir" "Ən son istifadə" - "Ətraflı məlumat" + "İcazələrin İdarə Panelinə Baxın" "Sistemi göstərin" "Sistemi gizlədin" "Tətbiq yoxdur" @@ -90,9 +91,23 @@ "Cari icazələr" "Tətbiq hazırlanır..." "Naməlum" - "İcazədən istifadə" - "Son giriş: %1$s\n%2$s giriş" - "Son giriş: %1$s\n%2$s giriş (arxa fonda %3$s giriş)" + "İdarə paneli" + + Son giriş: %1$s\n%2$s giriş + Son giriş: %1$s\n%2$s giriş + + + Son giriş: %1$s\n%2$s giriş (arxa fonda %3$s) + Son giriş: %1$s\n%2$s giriş (arxa fonda %3$s) + + + Son giriş: %1$s\n%2$s giriş\nMüddət: %3$s + Son giriş: %1$s\n%2$s giriş\nMüddət: %3$s + + + Son giriş: %1$s\n%2$s giriş (arxa fonda %3$s)\nMüddət: %3$s + Son giriş: %1$s\n%2$s giriş (arxa fonda%3$s)\nMüddət: %3$s + "Hər hansı icazə" "İstənilən vaxt" "Son 7 gün" @@ -135,6 +150,7 @@ "%1$s üçün %2$s icazəsi əlçatan deyil." "İcazələrin istifadəsi ilə bağlı ətraflı məlumata baxın" "Son giriş: %1$s" + "Heç vaxt giriş edilməyib" "İcazə verilib" "Yalnız istifadədə olarkən icazə verildi" "Ləğv edildi" diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml index 959110945..dceb94e08 100644 --- a/res/values-b+sr+Latn/strings.xml +++ b/res/values-b+sr+Latn/strings.xml @@ -39,6 +39,7 @@ "Dozvoli samo dok se aplikacija koristi" "Aplikacije" "Dozvole za aplikacije" + "Menadžer dozvola" "Ne pitaj ponovo" "Nema dozvola" "Dodatne dozvole" @@ -52,7 +53,7 @@ "obavlja nepoznatu radnju" "Aplikacije sa dozvolom: %1$d od %2$d" "Nedavna upotreba" - "Prikaži detalje" + "Prikaži kontrolnu tablu za dozvole" "Prikaži sistemske" "Sakrij sistemske" "Nema aplikacija" @@ -91,9 +92,27 @@ "Aktuelne dozvole" "Aplikacija se priprema…" "Nepoznato" - "Korišćenje dozvola" - "Poslednji pristup: %1$s\n%2$s pristupa" - "Poslednji pristup: %1$s\n%2$s pristupa (%3$s u pozadini)" + "Kontrolna tabla" + + Poslednji pristup: %1$s\n%2$s pristup + Poslednji pristup: %1$s\n%2$s pristupa + Poslednji pristup: %1$s\n%2$s pristupa + + + Poslednji pristup: %1$s\n%2$s pristup (%3$s u pozadini) + Poslednji pristup: %1$s\n%2$s pristupa (%3$s u pozadini) + Poslednji pristup: %1$s\n%2$s pristupa (%3$s u pozadini) + + + Poslednji pristup: %1$s\n%2$s pristup\nTrajanje: %3$s + Poslednji pristup: %1$s\n%2$s pristupa\nTrajanje: %3$s + Poslednji pristup: %1$s\n%2$s pristupa\nTrajanje: %3$s + + + Poslednji pristup: %1$s\n%2$s pristup (%3$s u pozadini)\nTrajanje: %3$s + Poslednji pristup: %1$s\n%2$s pristupa (%3$s u pozadini)\nTrajanje: %3$s + Poslednji pristup: %1$s\n%2$s pristupa (%3$s u pozadini)\nTrajanje: %3$s + "Bilo koja dozvola" "Bilo kada" "Poslednjih 7 dana" @@ -136,6 +155,7 @@ "Aplikacija %1$s nije pristupila dozvoli %2$s." "Pregledajte detaljne dozvole za korišćenje" "Poslednji pristup: %1$s" + "Bez pristupa" "Dozvoljeno" "Dozvoljeno samo dok se aplikacija koristi" "Odbijeno" diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml index b8b8a20eb..c39d4badc 100644 --- a/res/values-be/strings.xml +++ b/res/values-be/strings.xml @@ -39,6 +39,7 @@ "Дазволіць толькі ў актыўным рэжыме праграмы" "Праграмы" "Дазволы праграмы" + "Менеджар дазволаў" "Больш не пытацца" "Няма дазволаў" "Дадатковыя дазволы" @@ -53,7 +54,7 @@ "выканаць невядомае дзеянне" "%1$d з %2$d праграм з дазволам" "Нядаўняе выкарыстанне" - "Паказаць падрабязныя звесткі" + "Паказаць панэль кіравання" "Паказаць сістэмныя" "Схаваць сістэмныя" "Няма праграм" @@ -92,9 +93,31 @@ "Бягучыя дазволы" "Падрыхтоўка праграмы…" "Невядома" - "Выкарыстанне дазволаў" - "Апошні доступ: %1$s\nКолькасць доступаў – %2$s" - "Апошні доступ: %1$s\nКолькасць доступаў – %2$s (у фонавым рэжыме – %3$s)" + "Панэль кіравання" + + Апошні доступ: %1$s\n%2$s доступ + Апошні доступ: %1$s\n%2$s доступы + Апошні доступ: %1$s\n%2$s доступаў + Апошні доступ: %1$s\n%2$s доступу + + + Апошні доступ: %1$s\n%2$s доступ (у фонавым рэжыме: %3$s) + Апошні доступ: %1$s\n%2$s доступы (у фонавым рэжыме: %3$s) + Апошні доступ: %1$s\n%2$s доступаў (у фонавым рэжыме: %3$s) + Апошні доступ: %1$s\n%2$s доступу (у фонавым рэжыме: %3$s) + + + Апошні доступ: %1$s\n%2$s доступ\nПрацягласць: %3$s + Апошні доступ: %1$s\n%2$s доступы\nПрацягласць: %3$s + Апошні доступ: %1$s\n%2$s доступаў\nПрацягласць: %3$s + Апошні доступ: %1$s\n%2$s доступу\nПрацягласць: %3$s + + + Апошні доступ: %1$s\n%2$s доступ (у фонавым рэжыме: %3$s)\nПрацягласць: %3$s + Апошні доступ: %1$s\n%2$s доступы (у фонавым рэжыме: %3$s)\nПрацягласць: %3$s + Апошні доступ: %1$s\n%2$s доступаў (у фонавым рэжыме: %3$s)\nПрацягласць: %3$s + Апошні доступ: %1$s\n%2$s доступу (у фонавым рэжыме: %3$s)\nПрацягласць: %3$s + "Любы дазвол" "За любы час" "За апошнія 7 дзён" @@ -137,6 +160,7 @@ "Праграма \"%1$s\" не атрымала доступу да функцыі \"%2$s\"." "Прагледзець звесткі пра выкарыстанне дазволаў" "Апошні доступ: %1$s" + "Без доступаў" "Дазволеныя" "Дазволена толькі падчас карыстання" "Адмоўленыя" diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml index 10770abdb..40ac6cdc7 100644 --- a/res/values-bg/strings.xml +++ b/res/values-bg/strings.xml @@ -39,6 +39,7 @@ "Разрешаване само докато приложението се използва" "Приложения" "Разрешения за приложенията" + "Мениджър на разрешенията" "Без повторно запитване" "Няма разрешения" "Допълнителни разрешения" @@ -51,7 +52,7 @@ "извършване на неизвестно действие" "%1$d от %2$d приложения имат разрешение" "Скорошна употреба" - "Преглед на подробностите" + "Табло за управл. на разреш.: Преглед" "Показване на системните приложения" "Скриване на системните приложения" "Няма приложения" @@ -90,9 +91,23 @@ "Текущи разрешения" "Приложението се подготвя…" "Неизвестно" - "Използване на разрешенията" - "Последен достъп: %1$s \n %2$s осъществявания на достъп" - "Последен достъп: %1$s\n%2$s осъществявания на достъп (%3$s на заден план)" + "Табло за управление" + + Последен достъп: %1$s\n%2$s осъществявания на достъп + Последен достъп: %1$s\n%2$s осъществяване на достъп + + + Последен достъп: %1$s\n%2$s осъществявания на достъп (%3$s на заден план) + Последен достъп: %1$s\n%2$s осъществяване на достъп (%3$s на заден план) + + + Последен достъп: %1$s\n%2$s осъществявания на достъп\nПродължителност: %3$s + Последен достъп: %1$s\n%2$s осъществяване на достъп\nПродължителност: %3$s + + + Последен достъп: %1$s\n%2$s осъществявания на достъп (%3$s на заден план)\nПродължителност: %3$s + Последен достъп: %1$s\n%2$s осъществяване на достъп (%3$s на заден план)\nПродължителност: %3$s + "Всички разрешения" "По всяко време" "Последните 7 дни" @@ -135,6 +150,7 @@ "Приложението %1$s не е осъществило достъп до %2$s." "Преглед на подробности за използването на разрешенията" "Последен достъп: %1$s" + "Никога не е осъществяван достъп" "Разрешено" "Разрешено само при използване" "Отказано" diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml index 85168da0b..cfe43bc7e 100644 --- a/res/values-bn/strings.xml +++ b/res/values-bn/strings.xml @@ -39,6 +39,7 @@ "শুধুমাত্র অ্যাপ ব্যবহারের সময়ই অনুমতি দিন" "অ্যাপ" "অ্যাপের অনুমতি" + "অনুমতি ম্যানেজার" "আর জিজ্ঞেস না করার জন্য বলুন" "কোনও অনুমতি নেই" "অতিরিক্ত অনুমতি" @@ -51,7 +52,7 @@ "কোনও অজানা অ্যাকশন নিন" "%2$dটি অ্যাপের মধ্যে %1$dটি অনুমোদিত" "সাম্প্রতিক ব্যবহার" - "বিবরণ দেখুন" + "অনুমতির ড্যাশবোর্ড দেখুন" "সিস্টেম অ্যাপ দেখুন" "সিস্টেম অ্যাপ লুকান" "কোনও অ্যাপ নেই" @@ -90,9 +91,23 @@ "বর্তমান অনুমতি" "অ্যাপ স্টেজ করা হচ্ছে…" "অজানা" - "অনুমতির ব্যবহার" - "শেষবার অ্যাক্সেস করা হয়েছে: %1$s\n%2$sটি অ্যাক্সেস" - "শেষবার অ্যাক্সেস করা হয়েছে: %1$s\n%2$sটি অ্যাক্সেস (ব্যাকগ্রাউন্ডে%3$sটি)" + "ড্যাশবোর্ড" + + শেষবার অ্যাক্সেস করা হয়েছে: %1$s\n%2$sবার অ্যাক্সেস করা হয়েছে + শেষবার অ্যাক্সেস করা হয়েছে: %1$s\n%2$sবার অ্যাক্সেস করা হয়েছে + + + শেষবার অ্যাক্সেস করা হয়েছে: %1$s\n%2$sবার অ্যাক্সেস করা হয়েছে (ব্যাকগ্রাউন্ডে %3$sবার) + শেষবার অ্যাক্সেস করা হয়েছে: %1$s\n%2$sবার অ্যাক্সেস করা হয়েছে (ব্যাকগ্রাউন্ডে %3$sবার) + + + শেষবার অ্যাক্সেস করা হয়েছে: %1$s\n%2$sবার অ্যাক্সেস করা হয়েছে\nসময়সীমা: %3$s + শেষবার অ্যাক্সেস করা হয়েছে: %1$s\n%2$sবার অ্যাক্সেস করা হয়েছে\nসময়সীমা: %3$s + + + শেষবার অ্যাক্সেস করা হয়েছে: %1$s\n%2$sবার অ্যাক্সেস (ব্যাকগ্রাউন্ডে %3$sবার)\nসময়সীমা: %3$s + শেষবার অ্যাক্সেস করা হয়েছে: %1$s\n%2$sবার অ্যাক্সেস (ব্যাকগ্রাউন্ডে %3$sবার)\nসময়সীমা: %3$s + "যেকোন অনুমতি" "যেকোনও সময়" "গত ৭ দিন" @@ -135,6 +150,7 @@ "%1$s আপনার %2$s অ্যাক্সেস করতে পারেনি।" "বিস্তারিত অনুমতির ব্যবহার দেখুন" "শেষবার অ্যাক্সেস করা হয়েছে: %1$s" + "কখনও অ্যাক্সেস করা হয়নি" "অনুমোদিত" "শুধুমাত্র ব্যবহার করার সময় অনুমোদিত" "প্রত্যাখ্যান করা হয়েছে" diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml index cebacca7f..3d153b4a1 100644 --- a/res/values-bs/strings.xml +++ b/res/values-bs/strings.xml @@ -39,6 +39,7 @@ "Dozvoli samo kada se aplikacija koristi" "Aplikacije" "Odobrenja za aplikaciju" + "Upravitelj dopuštenja" "Ne pitaj ponovo" "Nema odobrenja" "Dodatna odobrenja" @@ -52,7 +53,7 @@ "izvrši nepoznatu radnju" "Aplikacije s odobrenjem: %1$d od %2$d" "Nedavno korištenje" - "Prikaži detalje" + "Prikaži kontrolnu tablu za odobrenja" "Prikaži sistemske aplikacije" "Sakrij sistemske aplikacije" "Nijedna aplikacija" @@ -91,9 +92,27 @@ "Postojeća odobrenja" "Pripremanje aplikacije…" "Nepoznato" - "Korištenje odobrenja" - "Posljednji pristup: %1$s\n – Broj pristupa: %2$s" - "Posljednji pristup: %1$s\n– Broj pristupa: %2$s ( %3$su pozadini)" + "Kontrolna tabla" + + Posljednji pristup: %1$s\n%2$s pristup + Posljednji pristup: %1$s\n%2$s pristupa + Posljednji pristup: %1$s\n%2$s pristupa + + + Posljednji pristup: %1$s\n%2$s pristup (%3$s u pozadini) + Posljednji pristup: %1$s\n%2$s pristupa (%3$s u pozadini) + Posljednji pristup: %1$s\n%2$s pristupa (%3$s u pozadini) + + + Posljednji pristup: %1$s\n%2$s pristup \nTrajanje: %3$s + Posljednji pristup: %1$s\n%2$s pristupa \nTrajanje: %3$s + Posljednji pristup: %1$s\n%2$s pristupa \nTrajanje: %3$s + + + Posljednji pristup: %1$s\n%2$s pristup (%3$s u pozadini)\nTrajanje: %3$s + Posljednji pristup: %1$s\n%2$s pristupa (%3$s u pozadini)\nTrajanje: %3$s + Posljednji pristup: %1$s\n%2$s pristupa (%3$s u pozadini)\nTrajanje: %3$s + "Sva odobrenja" "Bilo kad" "Posljednjih 7 dana" @@ -136,6 +155,7 @@ "Aplikacija %1$s nije pristupila vašem odobrenju %2$s." "Vidi detaljno korištenje odobrenja" "Posljednji pristup: %1$s" + "Bez pristupa" "Dozvoljeno" "Dozvoljeno samo tokom upotrebe" "Odbijeno" diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml index 5adaa3e53..633fba207 100644 --- a/res/values-ca/strings.xml +++ b/res/values-ca/strings.xml @@ -39,6 +39,7 @@ "Permet només mentre s\'utilitza l\'aplicació" "Aplicacions" "Permisos d\'aplicacions" + "Gestor de permisos" "No m\'ho tornis a preguntar" "Sense permisos" "Permisos addicionals" @@ -51,7 +52,7 @@ "dur a terme una acció desconeguda" "%1$d de %2$d aplicacions permeses" "Ús recent" - "Mostra els detalls" + "Consulta el tauler de permisos" "Mostra les aplicacions del sistema" "Amaga les aplicacions del sistema" "Cap aplicació" @@ -90,9 +91,23 @@ "Permisos actuals" "S\'està preparant la instal·lació de l\'aplicació…" "Desconegut" - "Ús de permisos" - "Últim accés: %1$s\n%2$s accessos" - "Últim accés: %1$s\n%2$s accessos (%3$s en segon pla)" + "Tauler" + + Últim accés: %1$s\n%2$s accessos + Últim accés: %1$s\n%2$s accés + + + Últim accés: %1$s\n%2$s accessos (%3$s en segon pla) + Últim accés: %1$s\n%2$s accés (%3$s en segon pla) + + + Últim accés: %1$s\n%2$s accessos\nDurada: %3$s + Últim accés: %1$s\n%2$s accés\nDurada: %3$s + + + Últim accés: %1$s\n%2$s accessos (%3$s en segon pla)\nDurada: %3$s + Últim accés: %1$s\n%2$s accés (%3$s en segon pla)\nDurada: %3$s + "Qualsevol permís" "En qualsevol moment" "7 últims dies" @@ -135,6 +150,7 @@ "%1$s no ha accedit al permís %2$s." "Mostra dades detallades sobre l\'ús de permisos" "Últim accés: %1$s" + "No hi ha accedit mai" "Acceptats" "Només es permeten mentre s\'utilitzen" "Denegats" @@ -194,7 +210,7 @@ "Aplicació per filtrar trucades" "Aplicació complementària de trucades" "Aplicació projecció del cotxe" - "No admet els perfils professionals" + "No admet perfils professionals" "Nota: si reinicies el dispositiu i has definit un bloqueig de pantalla, l\'aplicació no s\'iniciarà fins que no desbloquegis el dispositiu." "L\'assistent podrà llegir informació sobre les aplicacions que s\'utilitzen al teu sistema; també podrà accedir a la informació que es veu en pantalla o a què accedeixes des de les aplicacions." "Comparteix les dades de depuració" diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml index 8664a2b60..4d9b29c2f 100644 --- a/res/values-cs/strings.xml +++ b/res/values-cs/strings.xml @@ -39,6 +39,7 @@ "Povolit jen během používání aplikace" "Aplikace" "Oprávnění aplikací" + "Správce oprávnění" "Již se neptat" "Žádná oprávnění" "Další oprávnění" @@ -53,7 +54,7 @@ "provést neznámou akci" "Povoleno u %1$d%2$d aplikací" "Nedávné využití" - "Zobrazit podrobnosti" + "Zobrazit panel oprávnění" "Zobrazit systémové aplikace" "Skrýt systémové aplikace" "Žádné aplikace" @@ -92,9 +93,31 @@ "Aktuální oprávnění" "Příprava instalace…" "Neznámé" - "Využití oprávnění" - "Poslední přístup: %1$s\n%2$s použití" - "Poslední přístup: %1$s\n%2$s použití (%3$s na pozadí)" + "Panel" + + Poslední přístup: %1$s\n%2$s přístupy + Poslední přístup: %1$s\n%2$s přístupu + Poslední přístup: %1$s\n%2$s přístupů + Poslední přístup: %1$s\n%2$s přístup + + + Poslední přístup: %1$s\n%2$s přístupy (%3$s na pozadí) + Poslední přístup: %1$s\n%2$s přístupu (%3$s na pozadí) + Poslední přístup: %1$s\n%2$s přístupů (%3$s na pozadí) + Poslední přístup: %1$s\n%2$s přístup (%3$s na pozadí) + + + Poslední přístup: %1$s\n%2$s přístupy\nTrvání: %3$s + Poslední přístup: %1$s\n%2$s přístupu\nTrvání: %3$s + Poslední přístup: %1$s\n%2$s přístupů\nTrvání: %3$s + Poslední přístup: %1$s\n%2$s přístup\nTrvání: %3$s + + + Poslední přístup: %1$s\n%2$s přístupy (%3$s na pozadí)\nTrvání: %3$s + Poslední přístup: %1$s\n%2$s přístupu (%3$s na pozadí)\nTrvání: %3$s + Poslední přístup: %1$s\n%2$s přístupů (%3$s na pozadí)\nTrvání: %3$s + Poslední přístup: %1$s\n%2$s přístup (%3$s na pozadí)\nTrvání: %3$s + "Všechna oprávnění" "Kdykoli" "Posledních 7 dnů" @@ -137,6 +160,7 @@ "Aplikace %1$s nezískala přístup k oprávnění %2$s." "Zobrazit podrobné využití oprávnění" "Poslední přístup: %1$s" + "Žádný přístup" "Povoleno" "Povoleno pouze během používání" "Zamítnuto" diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml index d09556acb..da333fe0b 100644 --- a/res/values-da/strings.xml +++ b/res/values-da/strings.xml @@ -39,6 +39,7 @@ "Tillad kun, mens appen er i brug" "Apps" "Apptilladelser" + "Tilladelsesadministrator" "Spørg ikke igen" "Ingen tilladelser" "Yderligere tilladelser" @@ -51,7 +52,7 @@ "udføre en ukendt handling" "%1$d ud af %2$d apps har tilladelse" "Seneste brug" - "Se info" + "Se tilladelsesbetjeningspanel" "Vis system" "Skjul system" "Ingen apps" @@ -90,9 +91,23 @@ "Aktuelle tilladelser" "Forbereder appen…" "Ukendt" - "Brug af tilladelser" - "Seneste adgang: %1$s\n%2$s adgange" - "Seneste adgang: %1$s\n%2$s adgange (%3$s i baggrunden)" + "Betjeningspanel" + + Seneste adgang: %1$s\n%2$s adgang + Seneste adgang: %1$s\n%2$s adgange + + + Seneste adgang: %1$s\n%2$s adgange (%3$s i baggrunden) + Seneste adgang: %1$s\n%2$s adgange (%3$s i baggrunden) + + + Seneste adgang: %1$s\n%2$s adgang\nVarighed: %3$s + Seneste adgang: %1$s\n%2$s adgange\nVarighed: %3$s + + + Seneste adgang: %1$s\n%2$s adgang (%3$s i baggrunden)\nVarighed: %3$s + Seneste adgang: %1$s\n%2$s adgange (%3$s i baggrunden)\nVarighed: %3$s + "Enhver tilladelse" "Når som helst" "De seneste 7 dage" @@ -135,6 +150,7 @@ "%1$s har ikke adgang til din %2$s." "Se detaljeret brug af tilladelser" "Seneste adgang: %1$s" + "Ingen adgange" "Tilladt" "Tillades kun, mens de er i brug" "Afvist" diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index a945f32cb..540745a27 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -39,6 +39,7 @@ "Nur zulassen, wenn die App verwendet wird" "Apps" "App-Berechtigungen" + "Berechtigungsmanager" "Nicht mehr fragen" "Keine Berechtigungen" "Zusätzliche Berechtigungen" @@ -51,7 +52,7 @@ "Unbekannte Aktion durchführen" "%1$d von %2$d Apps mit Berechtigung" "Letzte Nutzungen" - "Details anzeigen" + "Berechtigungs-Dashboard anzeigen" "System-Apps einblenden" "System-Apps ausblenden" "Keine Apps" @@ -90,9 +91,23 @@ "Aktuelle Berechtigungen" "App wird vorbereitet…" "Unbekannt" - "Berechtigungsnutzung" - "Letzter Zugriff: %1$s\n%2$s Zugriffe" - "Letzter Zugriff: %1$s\n%2$s Zugriffe (%3$s im Hintergrund)" + "Dashboard" + + Letzter Zugriff: %1$s\n%2$s Zugriffe + Letzter Zugriff: %1$s\n%2$s Zugriff + + + Letzter Zugriff: %1$s\n%2$s Zugriffe (%3$s im Hintergrund) + Letzter Zugriff: %1$s\n%2$s Zugriff (%3$s im Hintergrund) + + + Letzter Zugriff: %1$s\n%2$s Zugriffe\nDauer: %3$s + Letzter Zugriff: %1$s\n%2$s Zugriff\nDauer: %3$s + + + Letzter Zugriff: %1$s\n%2$s Zugriffe (%3$s im Hintergrund)\nDauer: %3$s + Letzter Zugriff: %1$s\n%2$s Zugriff (%3$s im Hintergrund)\nDauer: %3$s + "Beliebige Berechtigung" "Beliebiger Zeitraum" "Letzte 7 Tage" @@ -135,6 +150,7 @@ "%1$s hat nicht auf %2$s zugegriffen." "Details zur Berechtigungsnutzung ansehen" "Letzter Zugriff: %1$s" + "Nie auf Berechtigung zugegriffen" "Zulässig" "Nur während der Verwendung erlaubt" "Abgelehnt" @@ -170,9 +186,9 @@ "Beenden erzwingen" "Einstellungen" "%s hat uneingeschränkten Zugriff auf dein Gerät" - "%s Bedienungshilfen haben uneingeschränkten Zugriff auf dein Gerät" - "%s kann deinen Bildschirm, deine Aktionen und Eingaben sehen, Aktionen ausführen und den Bildschirm steuern." - "Diese Dienste können deinen Bildschirm, deine Aktionen und Eingaben sehen, Aktionen ausführen und den Bildschirm steuern." + "%s Bedienungshilfen-Dienste haben uneingeschränkten Zugriff auf dein Gerät" + "%s kann deinen Bildschirm, deine Aktionen und deine Eingaben sehen, Aktionen ausführen und den Bildschirm steuern." + "Diese Dienste können deinen Bildschirm, deine Aktionen und deine Eingaben sehen, Aktionen ausführen und den Bildschirm steuern." "Standard-Apps" "Keine Standard-Apps" "Standardeinstellung für Arbeit" diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml index 500f7125f..93404c0eb 100644 --- a/res/values-el/strings.xml +++ b/res/values-el/strings.xml @@ -39,6 +39,7 @@ "Να επιτρέπεται μόνο όταν χρησιμοποιείται η εφαρμογή" "Εφαρμογές" "Άδειες εφαρμογών" + "Διαχείριση αδειών" "Να μην ερωτηθώ ξανά" "Δεν υπάρχουν άδειες" "Πρόσθετες άδειες" @@ -51,7 +52,7 @@ "εκτέλεση άγνωστης ενέργειας" "Επιτρέπονται %1$d από %2$d εφαρμογές" "Πρόσφατη χρήση" - "Προβολή λεπτομερειών" + "Προβολή πίνακα ελέγχου αδειών" "Εμφάνιση συστήματος" "Απόκρυψη συστήματος" "Δεν υπάρχουν εφαρμογές" @@ -90,9 +91,23 @@ "Τρέχουσες άδειες" "Σταδιακή διάθεση εφαρμογής…" "Άγνωστο" - "Χρήση δικαιωμάτων" - "Τελευταία πρόσβαση: %1$s\n%2$s προσβάσεις" - "Τελευταία πρόσβαση: %1$s\n%2$s προσβάσεις (%3$s στο παρασκήνιο)" + "Πίνακας ελέγχου" + + Τελευταία πρόσβαση: %1$s\n%2$s προσβάσεις + Τελευταία πρόσβαση: %1$s\n%2$s πρόσβαση + + + Τελευταία πρόσβαση: %1$s\n%2$s προσβάσεις (%3$s στο παρασκήνιο) + Τελευταία πρόσβαση: %1$s\n%2$s πρόσβαση (%3$s στο παρασκήνιο) + + + Τελευταία πρόσβαση: %1$s\n%2$s προσβάσεις\nΔιάρκεια: %3$s + Τελευταία πρόσβαση: %1$s\n%2$s πρόσβαση\nΔιάρκεια: %3$s + + + Τελευταία πρόσβαση: %1$s\n%2$s προσβάσεις (%3$s στο παρασκήνιο)\nΔιάρκεια: %3$s + Τελευταία πρόσβαση: %1$s\n%2$s πρόσβαση (%3$s στο παρασκήνιο)\nΔιάρκεια: %3$s + "Οποιαδήποτε άδεια" "Οποιαδήποτε στιγμή" "Τελευταίες 7 ημέρες" @@ -135,6 +150,7 @@ "Η εφαρμογή %1$s δεν απέκτησε πρόσβαση σε %2$s." "Προβολή λεπτομερούς χρήσης αδειών" "Τελευταία πρόσβαση: %1$s" + "Δεν έγινε ποτέ πρόσβαση" "Επιτρέπονται" "Επιτρέπεται μόνο κατά τη χρήση" "Απορρίφθηκαν" diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml index c1b477040..1eb445411 100644 --- a/res/values-en-rAU/strings.xml +++ b/res/values-en-rAU/strings.xml @@ -39,6 +39,7 @@ "Allow only while the app is in use" "Apps" "App permissions" + "Permission manager" "Don\'t ask again" "No permissions" "Additional permissions" @@ -51,7 +52,7 @@ "perform an unknown action" "%1$d of %2$d apps allowed" "Recent usage" - "View details" + "View permissions dashboard" "Show system" "Hide system" "No apps" @@ -90,9 +91,23 @@ "Current permissions" "Staging app…" "Unknown" - "Permissions usage" - "Last access: %1$s\n%2$s accesses" - "Last access: %1$s\n%2$s accesses (%3$s in background)" + "Dashboard" + + Last access: %1$s\n%2$s accesses + Last access: %1$s\n%2$s access + + + Last access: %1$s\n%2$s accesses (%3$s in background) + Last access: %1$s\n%2$s access (%3$s in background) + + + Last access: %1$s\n%2$s accesses\nDuration: %3$s + Last access: %1$s\n%2$s access\nDuration: %3$s + + + Last access: %1$s\n%2$s accesses (%3$s in background)\nDuration: %3$s + Last access: %1$s\n%2$s access (%3$s in background)\nDuration: %3$s + "Any permission" "Any time" "Last 7 days" @@ -135,6 +150,7 @@ "%1$s has not accessed your %2$s." "View detailed permissions usage" "Last access: %1$s" + "Never accessed" "Allowed" "Allowed only while in use" "Denied" diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml index c1b477040..1eb445411 100644 --- a/res/values-en-rCA/strings.xml +++ b/res/values-en-rCA/strings.xml @@ -39,6 +39,7 @@ "Allow only while the app is in use" "Apps" "App permissions" + "Permission manager" "Don\'t ask again" "No permissions" "Additional permissions" @@ -51,7 +52,7 @@ "perform an unknown action" "%1$d of %2$d apps allowed" "Recent usage" - "View details" + "View permissions dashboard" "Show system" "Hide system" "No apps" @@ -90,9 +91,23 @@ "Current permissions" "Staging app…" "Unknown" - "Permissions usage" - "Last access: %1$s\n%2$s accesses" - "Last access: %1$s\n%2$s accesses (%3$s in background)" + "Dashboard" + + Last access: %1$s\n%2$s accesses + Last access: %1$s\n%2$s access + + + Last access: %1$s\n%2$s accesses (%3$s in background) + Last access: %1$s\n%2$s access (%3$s in background) + + + Last access: %1$s\n%2$s accesses\nDuration: %3$s + Last access: %1$s\n%2$s access\nDuration: %3$s + + + Last access: %1$s\n%2$s accesses (%3$s in background)\nDuration: %3$s + Last access: %1$s\n%2$s access (%3$s in background)\nDuration: %3$s + "Any permission" "Any time" "Last 7 days" @@ -135,6 +150,7 @@ "%1$s has not accessed your %2$s." "View detailed permissions usage" "Last access: %1$s" + "Never accessed" "Allowed" "Allowed only while in use" "Denied" diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml index c1b477040..1eb445411 100644 --- a/res/values-en-rGB/strings.xml +++ b/res/values-en-rGB/strings.xml @@ -39,6 +39,7 @@ "Allow only while the app is in use" "Apps" "App permissions" + "Permission manager" "Don\'t ask again" "No permissions" "Additional permissions" @@ -51,7 +52,7 @@ "perform an unknown action" "%1$d of %2$d apps allowed" "Recent usage" - "View details" + "View permissions dashboard" "Show system" "Hide system" "No apps" @@ -90,9 +91,23 @@ "Current permissions" "Staging app…" "Unknown" - "Permissions usage" - "Last access: %1$s\n%2$s accesses" - "Last access: %1$s\n%2$s accesses (%3$s in background)" + "Dashboard" + + Last access: %1$s\n%2$s accesses + Last access: %1$s\n%2$s access + + + Last access: %1$s\n%2$s accesses (%3$s in background) + Last access: %1$s\n%2$s access (%3$s in background) + + + Last access: %1$s\n%2$s accesses\nDuration: %3$s + Last access: %1$s\n%2$s access\nDuration: %3$s + + + Last access: %1$s\n%2$s accesses (%3$s in background)\nDuration: %3$s + Last access: %1$s\n%2$s access (%3$s in background)\nDuration: %3$s + "Any permission" "Any time" "Last 7 days" @@ -135,6 +150,7 @@ "%1$s has not accessed your %2$s." "View detailed permissions usage" "Last access: %1$s" + "Never accessed" "Allowed" "Allowed only while in use" "Denied" diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml index c1b477040..1eb445411 100644 --- a/res/values-en-rIN/strings.xml +++ b/res/values-en-rIN/strings.xml @@ -39,6 +39,7 @@ "Allow only while the app is in use" "Apps" "App permissions" + "Permission manager" "Don\'t ask again" "No permissions" "Additional permissions" @@ -51,7 +52,7 @@ "perform an unknown action" "%1$d of %2$d apps allowed" "Recent usage" - "View details" + "View permissions dashboard" "Show system" "Hide system" "No apps" @@ -90,9 +91,23 @@ "Current permissions" "Staging app…" "Unknown" - "Permissions usage" - "Last access: %1$s\n%2$s accesses" - "Last access: %1$s\n%2$s accesses (%3$s in background)" + "Dashboard" + + Last access: %1$s\n%2$s accesses + Last access: %1$s\n%2$s access + + + Last access: %1$s\n%2$s accesses (%3$s in background) + Last access: %1$s\n%2$s access (%3$s in background) + + + Last access: %1$s\n%2$s accesses\nDuration: %3$s + Last access: %1$s\n%2$s access\nDuration: %3$s + + + Last access: %1$s\n%2$s accesses (%3$s in background)\nDuration: %3$s + Last access: %1$s\n%2$s access (%3$s in background)\nDuration: %3$s + "Any permission" "Any time" "Last 7 days" @@ -135,6 +150,7 @@ "%1$s has not accessed your %2$s." "View detailed permissions usage" "Last access: %1$s" + "Never accessed" "Allowed" "Allowed only while in use" "Denied" diff --git a/res/values-en-rXC/strings.xml b/res/values-en-rXC/strings.xml index f75d663bd..ee669929a 100644 --- a/res/values-en-rXC/strings.xml +++ b/res/values-en-rXC/strings.xml @@ -39,6 +39,7 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‏‎‏‎‎‏‏‏‏‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‏‎‎‎‎‏‏‎‏‏‎‏‏‎‎‏‎‏‏‎‏‎‏‎‎‏‏‎Allow only while the app is in use‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‎‏‏‎‎‎‏‎‎‎‎‎‏‏‎‎‏‎‎‏‎‏‏‏‏‎‎‎‏‏‏‎‏‏‎‏‏‏‎‏‏‏‏‏‎‎‏‎‏‎‏‏‏‏‏‎Apps‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‏‎‎‎‏‏‏‎‏‎‏‏‏‎‎‏‏‏‎‏‎‏‎‏‏‏‎‎‎‎‏‎‏‎‏‎‏‏‎‏‎‎‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎App permissions‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‏‏‎‎‎‏‎‏‏‎‎‏‎‏‎‏‎‏‏‏‏‎‏‎‎‏‏‎‎‏‎‏‏‏‎‏‏‎‏‏‎‎‏‎‏‎‏‎‎‎‏‏‎‎‏‎‎Permission manager‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‎‏‏‎‎‏‏‎‎‏‎‎‏‏‏‎‏‎‎‏‎‏‏‎‏‏‏‏‏‏‎‎‎‏‏‎‎‏‏‏‏‎‎‏‎‏‏‏‎‏‏‏‏‎‎Don\'t ask again‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‏‎‎‎‏‏‎‎‎‏‎‏‎‎‎‎‏‎‎‎‏‎‎‎‏‎‎‏‎‎‏‏‎‏‏‏‏‏‏‏‎‎‏‏‎‎‎‎No permissions‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‏‏‏‏‎‎‏‏‎‎‏‏‏‏‎‏‎‎‎‏‏‎‏‎‏‎‏‎‎‏‏‎‎‏‏‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‎‎Additional permissions‎‏‎‎‏‎" @@ -51,7 +52,7 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‏‎‎‏‏‎‏‏‎‏‏‎‎‎‏‎‎‎‎‏‏‎‎‎‎‎‎‏‏‎‏‏‎‏‏‏‎‏‏‏‎‏‏‎‎‏‎‎‎‏‏‎‎‏‎‏‎perform an unknown action‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‎‏‎‎‏‎‏‎‎‏‎‏‎‏‎‎‎‎‎‎‎‎‏‎‎‎‏‏‎‏‎‎‏‏‎‎‏‏‎‏‎‎‏‎‏‎‏‎‎‏‏‏‏‎‎‏‎‎‏‏‎%1$d‎‏‎‎‏‏‏‎ of ‎‏‎‎‏‏‎%2$d‎‏‎‎‏‏‏‎ apps allowed‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‏‎‏‎‎‏‏‎‏‎‎‎‏‏‎‏‏‏‎‎‏‎‎‏‏‎‏‏‏‏‎‏‎‏‏‏‎‏‎‏‏‏‏‏‏‎‏‏‏‎‎‎‎Recent usage‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‏‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‏‎‎‎‏‎‎‏‎‎‏‎‎‏‏‏‏‎‎‎‏‎‎‏‏‏‎‏‏‏‏‎‏‏‏‏‎View details‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‏‎‏‏‎‏‏‏‏‎‏‎‎‎‏‎‏‏‏‏‎‏‎‎‏‏‏‏‎‏‏‎‏‏‎‎‎‎‎‎‏‎‏‎‎‏‎‎‎‎‏‏‎‏‎View Permissions Dashboard‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‎‎‏‎‏‎‎‏‎‏‏‎‎‎‎‏‏‏‎‎‏‏‎‎‏‎‎‏‎‎‎‎‏‏‎‏‎‎‎‎‎‎‏‏‏‏‎‏‏‎‎‏‎‏‎Show system‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‏‎‎‎‏‏‏‏‏‎‎‏‏‎‎‎‏‏‎‏‎‎‏‎‎‏‏‎‏‏‏‎‎‎‏‏‎‏‏‎‏‏‎‎‏‏‎‎‏‏‏‎‎‎‏‎‎Hide system‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‎‎‎‏‏‎‎‎‏‎‏‎‎‏‏‎‏‎‎‏‎‏‏‏‏‎‎‎‎‏‎‏‏‏‎‏‎‏‎‎‏‏‏‎No apps‎‏‎‎‏‎" @@ -90,9 +91,23 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‏‎‎‏‏‏‎‏‎‎‏‎‎‏‎‏‏‏‎‏‎‏‏‏‎‎‏‏‎‏‎‏‏‎‎‎‎‎‎‎‎‎‏‎‎‏‎‏‎‏‎‏‎‏‏‎‏‎Current permissions‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‏‏‏‎‎‏‏‎‎‏‎‎‏‏‏‎‏‏‎‎‎‏‎‏‏‎‏‎‎‎‎‏‎‎‎‏‎‎‏‎‎‎‏‎‏‏‎‏‏‎‎‎‏‎‏‏‎Staging app…‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‎‎‏‏‎‎‎‏‎‏‏‎‎‎‎‎‎‏‎‏‎‎‎‎‎‎‎‏‎‏‎‏‎‏‏‎‎‎‏‎‏‏‏‏‏‎‏‏‎‏‏‏‏‎Unknown‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‏‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‎‏‏‎‎‏‎‏‏‏‏‏‎‏‏‎‏‏‏‏‏‎‏‏‏‏‎‎‏‎‏‏‎‏‎‏‎Permissions usage‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‎‏‏‏‎‎‎‏‏‏‎‏‏‏‎‎‏‏‏‎‏‏‎‎‏‏‏‏‏‎‏‏‎‏‏‎‎‎‎‎‎‏‎‎‏‏‎‎‎‏‏‏‎‏‎‏‎Last access: ‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎ accesses‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‏‎‏‎‏‎‏‎‎‏‎‏‎‎‏‏‎‎‎‎‎‏‏‏‎‏‎‎‎‏‏‏‏‎‎‏‎‏‏‏‎‏‎‎‎‎‎‎‎‏‏‎‎‎‎‏‎Last access: ‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎ accesses (‎‏‎‎‏‏‎%3$s‎‏‎‎‏‏‏‎ in background)‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‏‏‏‏‎‏‏‏‏‏‎‎‎‏‎‏‏‏‏‏‏‎‎‏‏‎‏‏‎‎‏‎‏‎‎‏‏‎‏‏‏‎‎‏‎‏‏‎‏‎‎‎‎‏‏‎Dashboard‎‏‎‎‏‎" + + ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‏‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‎‎‎‎‎‏‎‎‎‏‎‎‎‏‏‎‏‏‏‎‎‎‎‏‏‎‏‎‏‏‏‏‏‎‎‏‎Last access: ‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎ accesses‎‏‎‎‏‎ + ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‏‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‎‎‎‎‎‏‎‎‎‏‎‎‎‏‏‎‏‏‏‎‎‎‎‏‏‎‏‎‏‏‏‏‏‎‎‏‎Last access: ‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎ access‎‏‎‎‏‎ + + + ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‏‎‏‎‎‏‏‎‏‎‏‏‎‏‎‎‎‎‏‏‎‏‏‎‏‏‎‏‏‎‎‏‎‎‏‏‎‏‏‎‏‎‎‎‎‎‎‎‎‏‏‎‎Last access: ‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎ accesses (‎‏‎‎‏‏‎%3$s‎‏‎‎‏‏‏‎ in background)‎‏‎‎‏‎ + ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‏‎‏‎‎‏‏‎‏‎‏‏‎‏‎‎‎‎‏‏‎‏‏‎‏‏‎‏‏‎‎‏‎‎‏‏‎‏‏‎‏‎‎‎‎‎‎‎‎‏‏‎‎Last access: ‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎ access (‎‏‎‎‏‏‎%3$s‎‏‎‎‏‏‏‎ in background)‎‏‎‎‏‎ + + + ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‎‏‏‎‏‏‏‏‎‏‎‎‎‎‎‎‏‏‏‎‎‎‎‏‏‏‎‏‎‎‎‎‎‏‎‎‎‏‏‏‎‎‏‎‎‎‏‏‎‏‏‏‎‎‏‎‎Last access: ‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎ accesses‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Duration: ‎‏‎‎‏‏‎%3$s‎‏‎‎‏‏‏‎‎‏‎‎‏‎ + ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‎‏‏‎‏‏‏‏‎‏‎‎‎‎‎‎‏‏‏‎‎‎‎‏‏‏‎‏‎‎‎‎‎‏‎‎‎‏‏‏‎‎‏‎‎‎‏‏‎‏‏‏‎‎‏‎‎Last access: ‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎ access‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Duration: ‎‏‎‎‏‏‎%3$s‎‏‎‎‏‏‏‎‎‏‎‎‏‎ + + + ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‏‎‏‎‏‎‏‎‎‏‏‏‏‏‎‎‎‎‎‎‏‏‎‏‏‎‏‏‏‏‎‎‎‎‎‏‎‎‎‎‏‏‎‎‏‏‎‎‎‎‏‏‎‏‎‎Last access: ‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎ accesses (‎‏‎‎‏‏‎%3$s‎‏‎‎‏‏‏‎ in background)‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Duration: ‎‏‎‎‏‏‎%3$s‎‏‎‎‏‏‏‎‎‏‎‎‏‎ + ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‏‎‏‎‏‎‏‎‎‏‏‏‏‏‎‎‎‎‎‎‏‏‎‏‏‎‏‏‏‏‎‎‎‎‎‏‎‎‎‎‏‏‎‎‏‏‎‎‎‎‏‏‎‏‎‎Last access: ‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎ access (‎‏‎‎‏‏‎%3$s‎‏‎‎‏‏‏‎ in background)‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Duration: ‎‏‎‎‏‏‎%3$s‎‏‎‎‏‏‏‎‎‏‎‎‏‎ + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‎‏‎‎‏‎‏‎‎‏‏‏‎‎‎‎‏‎‏‎‎‎‎‏‎‎‏‏‎‏‎‎‏‏‎‎‏‎‎‎‏‏‎‏‎‏‎‏‎‏‏‏‎Any permission‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‎‎‏‎‏‏‎‏‏‎‎‎‎‏‎‏‏‏‏‏‎‏‎‎‏‏‎‎‏‏‎‏‏‏‏‏‏‎‏‏‏‎‎‎‏‏‎‏‏‏‏‎‏‎‎‏‏‎Any time‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‏‏‎‎‎‎‎‎‏‏‎‏‏‎‏‎‎‎‎‏‎‏‏‏‎‎‏‎‏‏‎‏‏‎‏‏‏‎‎‎‏‎‎‏‏‏‎‎‎‏‎‏‎‎‎Last 7 days‎‏‎‎‏‎" @@ -135,6 +150,7 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‏‎‏‏‏‏‏‏‎‎‏‏‎‎‎‏‏‎‎‎‏‏‏‎‏‏‎‏‏‏‏‎‏‏‎‎‏‏‎‎‏‎‎‎‎‏‎‎‏‏‏‏‎‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ has not accessed your ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎.‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‎‎‏‏‎‎‎‏‏‏‏‎‏‏‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‏‎‏‏‏‏‏‎‎‎‏‏‎‏‎‏‎‏‏‏‏‏‎‎View detailed permissions usage‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‏‏‏‏‎‏‎‎‏‏‎‎‏‎‏‏‎‏‏‎‏‎‏‎‎‎‏‏‏‏‎‏‏‏‎‎‏‏‎‎‎‏‎‏‏‎‏‎‎‎‎‎‎Last access: ‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‏‏‏‏‏‎‎‎‏‏‏‎‎‎‎‏‏‏‎‏‏‎‏‎‎‎‎‏‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎Never accessed‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‎‏‎‎‏‎‎‎‏‎‏‏‎‏‏‏‎‏‏‎‎‎‎‎‎‎‏‎‎‎‏‎‏‏‏‏‏‎‎‏‏‏‏‎‏‏‏‎‎‎‏‏‏‏‎‎Allowed‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‏‎‎‏‏‏‏‎‎‎‎‏‏‎‎‏‎‎‏‎‎‏‏‏‏‎‎‎‏‎‏‎‎‏‎‎‏‏‎‎‎‎‎‎‏‏‏‏‎‎‏‏‏‎Allowed only while in use‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‏‎‎‏‏‏‎‏‎‎‎‏‎‎‏‏‏‎‏‎‎‎‏‎‎‏‎‎‏‎‎‎‎‏‎‏‎‏‏‎‏‏‎‏‎‎‎‎‎‏‏‎‎‎‏‏‎Denied‎‏‎‎‏‎" diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml index c51cc3e80..b4a273a40 100644 --- a/res/values-es-rUS/strings.xml +++ b/res/values-es-rUS/strings.xml @@ -39,6 +39,7 @@ "Permitir solo cuando la app está en uso" "Apps" "Permisos de la app" + "Administrador de permisos" "No volver a preguntar" "Sin permisos" "Permisos adicionales" @@ -51,7 +52,7 @@ "realizar una acción desconocida" "Se otorgó el permiso a %1$d de %2$d apps" "Uso reciente" - "Ver detalles" + "Ver panel de permisos" "Mostrar sistema" "Ocultar sistema" "Ninguna app" @@ -90,9 +91,23 @@ "Permisos actuales" "Preparando app…" "Desconocida" - "Uso de permisos" - "Último acceso: %1$s\n%2$s accesos" - "Último acceso: %1$s \n %2$s accesos (%3$s en segundo plano)" + "Panel" + + Último acceso: %1$s\n%2$s accesos + Último acceso: %1$s\n%2$s acceso + + + Último acceso: %1$s\n %2$s accesos (%3$s en segundo plano) + Último acceso: %1$s\n %2$s acceso (%3$s en segundo plano) + + + Último acceso: %1$s\n%2$s accesos\nDuración: %3$s + Último acceso: %1$s\n%2$s acceso\nDuración: %3$s + + + Último acceso: %1$s\n%2$s accesos (%3$s en segundo plano)\nDuración: %3$s + Último acceso: %1$s\n%2$s acceso (%3$s en segundo plano)\nDuración: %3$s + "Cualquier permiso" "Cualquier momento" "Últimos 7 días" @@ -135,6 +150,7 @@ "%1$s no accedió a %2$s." "Ver uso de permisos detallado" "Último acceso: %1$s" + "No accedió nunca" "Permitidos" "Permitidos solo durante el uso" "Rechazados" diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index 242e05b4d..6b7e736bd 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -39,6 +39,7 @@ "Permitir solo mientras la aplicación está en uso" "Aplicaciones" "Permisos de aplicaciones" + "Gestor de permisos" "No volver a preguntar" "Sin permisos" "Permisos adicionales" @@ -51,7 +52,7 @@ "realizar una acción desconocida" "%1$d de %2$d aplicaciones permitidas" "Uso reciente" - "Ver detalles" + "Ver panel de permisos" "Mostrar aplicaciones del sistema" "Ocultar aplicaciones del sistema" "No hay aplicaciones" @@ -90,9 +91,23 @@ "Permisos actuales" "Preparando aplicación…" "Desconocida" - "Uso de permisos" - "Último acceso: %1$s\n%2$s accesos" - "Último acceso: %1$s\n%2$s accesos (%3$s en segundo plano)" + "Panel" + + Último acceso: %1$s\n%2$s accesos + Último acceso: %1$s\n%2$s acceso + + + Último acceso: %1$s\n%2$s accesos (%3$s en segundo plano) + Último acceso: %1$s\n%2$s acceso (%3$s en segundo plano) + + + Último acceso: %1$s\n%2$s accesos\nDuración: %3$s + Último acceso: %1$s\n%2$s acceso\nDuración: %3$s + + + Último acceso: %1$s\n%2$s accesos (%3$s en segundo plano)\nDuración: %3$s + Último acceso: %1$s\n%2$s acceso (%3$s en segundo plano)\nDuración: %3$s + "Cualquier permiso" "Cualquier fecha" "Últimos 7 días" @@ -135,6 +150,7 @@ "%1$s no ha accedido a tu %2$s." "Ver el uso de permisos detallado" "Último acceso: %1$s" + "No se ha accedido nunca" "Permitidos" "Solo se permite mientras se usa" "Denegados" diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml index 092a649ae..401d9a57c 100644 --- a/res/values-et/strings.xml +++ b/res/values-et/strings.xml @@ -39,6 +39,7 @@ "Luba ainult rakenduse kasutamise ajal" "Rakendused" "Rakenduse load" + "Lubade haldur" "Ära enam küsi" "Lube pole" "Lisaload" @@ -51,7 +52,7 @@ "teeb tundmatu toimingu" "%1$d rakendust %2$d-st on lubatud" "Hiljutine kasutus" - "Kuva üksikasjad" + "Kuva lubade juhtpaneel" "Kuva süsteem" "Peida süsteem" "Rakendusi pole" @@ -90,9 +91,23 @@ "Praegused load" "Rakenduse koondamine …" "Tundmatu" - "Lubade kasutus" - "Viimane juurdepääs: %1$s\n%2$s juurdepääsu" - "Viimane juurdepääs: %1$s\n%2$s juurdepääsu (%3$s taustal)" + "Juhtpaneel" + + Viimane juurdepääs: %1$s\n%2$s juurdepääsu + Viimane juurdepääs: %1$s\n%2$s juurdepääs + + + Viimane juurdepääs: %1$s\n%2$s juurdepääsu (%3$s taustal) + Viimane juurdepääs: %1$s\n%2$s juurdepääs (%3$s taustal) + + + Viimane juurdepääs: %1$s\n%2$s juurdepääsu\nKestus: %3$s + Viimane juurdepääs: %1$s\n%2$s juurdepääs\nKestus: %3$s + + + Viimane juurdepääs: %1$s\n%2$s juurdepääsu (%3$s taustal)\nKestus: %3$s + Viimane juurdepääs: %1$s\n%2$s juurdepääs (%3$s taustal)\nKestus: %3$s + "Mis tahes luba" "Mis tahes ajal" "Viimased seitse päeva" @@ -135,6 +150,7 @@ "%1$s pole teie loale %2$s juurde pääsenud." "Kuva lubade kasutamise üksikasjad" "Viimane juurdepääs: %1$s" + "Pole kunagi juurde pääsetud" "Lubatud" "Lubatud ainult kasutuses olles" "Keeldutud" diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml index ef93d23d0..55d8ec15e 100644 --- a/res/values-eu/strings.xml +++ b/res/values-eu/strings.xml @@ -39,6 +39,7 @@ "Baimendu aplikazioa erabiltzen ari zarenean soilik" "Aplikazioak" "Aplikazio-baimenak" + "Baimenen kudeatzailea" "Ez galdetu berriro" "Ez dago baimenik" "Baimen gehigarriak" @@ -51,7 +52,7 @@ "Gauzatu ekintza ezezagunak" "%1$d/%2$d aplikaziok dute baimena" "Azkenaldiko erabilera" - "Ikusi xehetasunak" + "Ikusi baimenen panela" "Erakutsi sistema" "Ezkutatu sistema" "Ez dago aplikaziorik" @@ -90,9 +91,23 @@ "Uneko baimenak" "Aplikazioa prestatzen…" "Ezezaguna" - "Eskatutako baimenak" - "Azken sarbidea: %1$s\n%2$s aldiz" - "Azken sarbidea: %1$s\n%2$s aldiz (%3$s atzeko planoan)" + "Panela" + + Azken erabilera: %1$s\n%2$s aldiz + Azken erabilera: %1$s\n%2$s aldiz + + + Azken erabilera: %1$s\n%2$s aldiz (%3$s atzeko planoan) + Azken erabilera: %1$s\n%2$s aldiz (%3$s atzeko planoan) + + + Azken erabilera: %1$s\n%2$s aldiz\nIraupena %3$s + Azken erabilera: %1$s\n%2$s aldiz\nIraupena: %3$s + + + Azken erabilera: %1$s\n%2$s aldiz (%3$s atzeko planoan)\nIraupena: %3$s + Azken erabilera: %1$s\n%2$s aldiz (%3$s atzeko planoan)\nIraupena: %3$s + "Edozein baimen" "Edonoiz" "Azken 7 egunetan" @@ -135,6 +150,7 @@ "%1$s aplikazioak ez du atzitu %2$s." "Ikusi baimenen erabilera xehatua" "Azken sarbidea: %1$s" + "Ez da erabili inoiz" "Baimenduta" "Erabili bitartean soilik baimenduta" "Ukatuta" diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml index 7971579be..9c61f0f4b 100644 --- a/res/values-fa/strings.xml +++ b/res/values-fa/strings.xml @@ -39,6 +39,7 @@ "مجاز بودن تنها هنگام استفاده از برنامه" "برنامه" "مجوزهای برنامه" + "مدیر مجوز" "دوباره سؤال نشود" "مجوزی موجود نیست" "مجوزهای بیشتر" @@ -51,7 +52,7 @@ "انجام یک اقدام ناشناس" "%1$d برنامه از %2$d برنامه مجاز شد" "مصرف اخیر" - "مشاهده جزئیات" + "مشاهده داشبورد مجوزها" "نمایش سیستم" "پنهان کردن سیستم" "برنامه‌ای موجود نیست" @@ -90,9 +91,23 @@ "مجوزهای کنونی" "مرحله‌بندی برنامه…" "نامشخص" - "استفاده از مجوز" - "آخرین دسترسی: %1$s\n%2$s دسترسی" - "آخرین دسترسی: %1$s\n%2$s دسترسی (%3$s در پس‌زمینه)" + "داشبورد" + + آخرین دسترسی: %1$s\n%2$s دسترسی + آخرین دسترسی: %1$s\n%2$s دسترسی + + + آخرین دسترسی: %1$s\n%2$s دسترسی (%3$s دسترسی در پس‌زمینه) + آخرین دسترسی: %1$s\n%2$s دسترسی (%3$s دسترسی در پس‌زمینه) + + + آخرین دسترسی: %1$s\n مدت\n%2$s دسترسی: %3$s + آخرین دسترسی: %1$s\n مدت\n%2$s دسترسی: %3$s + + + آخرین دسترسی: %1$s\n%2$s دسترسی (%3$s دسترسی در پس‌زمینه)\nمدت: %3$s + آخرین دسترسی: %1$s\n%2$s دسترسی (%3$s دسترسی در پس‌زمینه)\nمدت: %3$s + "همه مجوزها" "هر زمانی" "۷ روز اخیر" @@ -135,6 +150,7 @@ "%1$s به %2$s شما دسترسی پیدا نکرده است." "مشاهده استفاده از مجوزها با جزئیات" "آخرین دسترسی: %1$s" + "هرگز دسترسی نداشته است" "مجاز" "مجاز فقط هنگام استفاده از برنامه" "رد شد" diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml index a1a5eec84..565848b55 100644 --- a/res/values-fi/strings.xml +++ b/res/values-fi/strings.xml @@ -39,6 +39,7 @@ "Salli vain, kun sovellusta käytetään" "Sovell." "Sovelluksen käyttöoikeudet" + "Käyttöoikeuksien ylläpitäjä" "Älä kysy enää" "Ei käyttöoikeuksia" "Lisäkäyttöoikeudet" @@ -51,7 +52,7 @@ "suorita tuntematon toiminto" "%1$d/%2$d sovelluksella käyttöoikeus" "Viimeaikainen käyttö" - "Näytä tiedot" + "Näytä käyttöoikeuksien hallintapaneeli" "Näytä järjestelmä" "Piilota järjestelmä" "Ei sovelluksia" @@ -90,9 +91,23 @@ "Nykyiset käyttöoikeudet" "Valmistellaan sovellusta…" "Tuntematon" - "Käyttöoikeuksien käyttö" - "Viimeinen käyttökerta: %1$s\n%2$s käyttöoikeutta" - "Viimeinen käyttökerta: %1$s\n%2$s käyttöoikeutta (%3$s taustalla)" + "Hallintapaneeli" + + Viimeinen käyttökerta: %1$s\n%2$s käyttökertaa + Viimeinen käyttökerta: %1$s\n%2$s käyttökerta + + + Viimeinen käyttökerta: %1$s\n%2$s käyttökertaa (%3$s taustalla) + Viimeinen käyttökerta: %1$s\n%2$s käyttökerta (%3$s taustalla) + + + Viimeinen käyttökerta: %1$s\n%2$s käyttökertaa\nKesto: %3$s + Viimeinen käyttökerta: %1$s\n%2$s käyttökerta\nKesto: %3$s + + + Viimeinen käyttökerta: %1$s\n%2$s käyttökertaa (%3$s taustalla)\nKesto: %3$s + Viimeinen käyttökerta: %1$s\n%2$s käyttökerta (%3$s taustalla)\nKesto: %3$s + "Kaikki käyttöoikeudet" "Milloin tahansa" "Viimeiset 7 päivää" @@ -135,6 +150,7 @@ "%1$s ei ole käyttänyt kohdetta %2$s." "Näytä tarkat käyttöoikeustiedot" "Viimeinen käyttökerta: %1$s" + "Ei ole koskaan käytetty" "Sallittu" "Sallittu vain käytön aikana" "Kielletty" diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml index ddd4ff904..1ce6e24cb 100644 --- a/res/values-fr-rCA/strings.xml +++ b/res/values-fr-rCA/strings.xml @@ -39,6 +39,7 @@ "Autoriser uniquement lorsque l\'appli est en cours d\'utilis." "Applications" "Autorisations des applications" + "Gestionnaire des autorisations" "Ne plus demander" "Aucune autorisation" "Autorisations supplémentaires" @@ -51,7 +52,7 @@ "effectuer une action inconnue" "%1$d applications autorisées sur %2$d" "Utilisation récente" - "Afficher les détails" + "Affich. tabl. de bord des autor." "Afficher le système" "Masquer le système" "Aucune application" @@ -90,9 +91,23 @@ "Autorisations actuelles" "Pré-production de l\'application en cours…" "Inconnu" - "Utilisation des autorisations" - "Dernier accès : %1$s\n%2$s accès" - "Dernier accès : %1$s\n%2$s accès (%3$s en arrière-plan)" + "Tableau de bord" + + Dernier accès : %1$s\n%2$s accès + Dernier accès : %1$s\n%2$s accès + + + Dernier accès : %1$s\n%2$s accès (%3$s en arrière-plan) + Dernier accès : %1$s\n%2$s accès (%3$s en arrière-plan) + + + Dernier accès : %1$s\n%2$s accès\nDurée : %3$s + Dernier accès : %1$s\n%2$s accès\nDurée : %3$s + + + Dernier accès : %1$s\n%2$s accès (%3$s en arrière-plan)\nDurée : %3$s + Dernier accès : %1$s\n%2$s accès (%3$s en arrière-plan)\nDurée : %3$s + "Toute autorisation" "À tout moment" "Les 7 derniers jours" @@ -135,6 +150,7 @@ "%1$s n\'a pas accédé à votre %2$s." "Afficher les autorisations d\'utilisation détaillées" "Dernier accès : %1$s" + "Aucun accès" "Autorisée" "Autorisée seulement durant l\'utilisation" "Refusé" diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index 254fe62ea..3d6c4da5b 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -39,6 +39,7 @@ "Autoriser seulement quand l\'appli est en cours d\'utilisation" "Applications" "Autorisations des applications" + "Gestionnaire d\'autorisations" "Ne plus demander" "Aucune autorisation" "Autorisations supplémentaires" @@ -51,7 +52,7 @@ "effectuer une action inconnue" "%1$d application(s) autorisée(s) sur %2$d" "Utilisation récente" - "Voir les détails" + "Voir tableau bord autorisations" "Afficher les applications système" "Masquer les applications système" "Aucune application" @@ -90,9 +91,23 @@ "Autorisations actuelles" "Pré-production de l\'application…" "Inconnu" - "Utilisation des autorisations" - "Dernier accès : %1$s\n%2$s accès" - "Dernier accès : %1$s\n%2$s accès (%3$s en arrière-plan)" + "Tableau de bord" + + Dernier accès : %1$s\n%2$s accès + Derniers accès : %1$s\n%2$s accès + + + Dernier accès : %1$s\n%2$s accès (%3$s en arrière-plan) + Derniers accès : %1$s\n%2$s accès (%3$s en arrière-plan) + + + Dernier accès : %1$s\n%2$s accès\nDurée : %3$s + Derniers accès : %1$s\n%2$s accès\nDurée : %3$s + + + Dernier accès : %1$s\n%2$s accès (%3$s en arrière-plan)\nDurée : %3$s + Derniers accès : %1$s\n%2$s accès (%3$s en arrière-plan)\nDurée : %3$s + "Toute autorisation" "Date indifférente" "7 derniers jours" @@ -135,6 +150,7 @@ "%1$s n\'a pas accédé à votre %2$s." "Afficher l\'utilisation détaillée des autorisations" "Dernier accès : %1$s" + "Aucun accès enregistré" "Autorisées" "Autorisées seulement pendant l\'utilisation" "Refusées" diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml index 0c688f00c..1237c6227 100644 --- a/res/values-gl/strings.xml +++ b/res/values-gl/strings.xml @@ -39,6 +39,7 @@ "Permitir só cando se estea utilizando a aplicación" "Aplicacións" "Permisos de aplicacións" + "Xestor de permisos" "Non preguntar de novo" "Sen permisos" "Permisos adicionais" @@ -51,7 +52,7 @@ "realiza unha acción descoñecida" "%1$d de %2$d aplicacións con permiso" "Uso recente" - "Ver detalles" + "Ver panel de control de permisos" "Mostrar sistema" "Ocultar sistema" "Sen aplicacións" @@ -90,9 +91,23 @@ "Permisos actuais" "Preparando aplicación…" "Nome descoñecido" - "Uso dos permisos" - "Último acceso: %1$s\n%2$s accessos" - "Último acceso: %1$s\n%2$s accesos (%3$s en segundo plano)" + "Panel de control" + + Último acceso: %1$s\n%2$s accesos + Último acceso: %1$s\n%2$s acceso + + + Último acceso: %1$s\n%2$s accesos (%3$s en segundo plano) + Último acceso: %1$s\n%2$s acceso (%3$s en segundo plano) + + + Último acceso: %1$s\n%2$s accesos\nDuración: %3$s + Último acceso: %1$s\n%2$s acceso\nDuración: %3$s + + + Último acceso: %1$s\n%2$s accesos (%3$s en segundo plano)\nDuración: %3$s + Último acceso: %1$s\n%2$s acceso (%3$s en segundo plano)\nDuración: %3$s + "Calquera permiso" "En calquera momento" "Últimos 7 días" @@ -135,6 +150,7 @@ "A aplicación %1$s non ten acceso a %2$s." "Consulta os detalles sobre o uso dos permisos" "Último acceso: %1$s" + "Non accedeu nunca" "Permiso concedido" "Só se permiten mentres se utilizan" "Permiso denegado" diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml index e1b6f87b5..e04bac0bd 100644 --- a/res/values-gu/strings.xml +++ b/res/values-gu/strings.xml @@ -39,6 +39,7 @@ "માત્ર ઍપ ઉપયોગમાં હોય ત્યારે જ મંજૂરી આપો" "ઍપ" "ઍપ પરવાનગીઓ" + "પરવાનગી મેનેજર" "ફરીથી પૂછશો નહીં" "કોઈ પરવાનગીઓ નથી" "વધારાની પરવાનગીઓ" @@ -51,7 +52,7 @@ "અજાણી ક્રિયા કરો" "%2$d માંથી %1$d ઍપની મંજૂરી છે" "તાજેતરનો વપરાશ" - "વિગતો જુઓ" + "પરવાનગીઓનું ડૅશબોર્ડ જુઓ" "સિસ્ટમ બતાવો" "સિસ્ટમ છુપાવો" "કોઈ ઍપ નથી" @@ -90,9 +91,23 @@ "વર્તમાન પરવાનગીઓ" "ઍપની પ્રક્રિયા ચાલુ છે…" "અજાણ" - "પરવાનગીઓનો ઉપયોગ" - "છેલ્લે થયેલો ઍક્સેસ: %1$s\n%2$s ઍક્સેસ" - "છેલ્લે થયેલો ઍક્સેસ: %1$s\n%2$s ઍક્સેસ (%3$s બૅકગ્રાઉન્ડમાં)" + "ડૅશબોર્ડ" + + છેલ્લો ઍક્સેસ: %1$s\n%2$s ઍક્સેસ + છેલ્લો ઍક્સેસ: %1$s\n%2$s ઍક્સેસ + + + છેલ્લો ઍક્સેસ: %1$s\n%2$s ઍક્સેસ (%3$s બૅકગ્રાઉન્ડમાં) + છેલ્લો ઍક્સેસ: %1$s\n%2$s ઍક્સેસ (%3$s બૅકગ્રાઉન્ડમાં) + + + છેલ્લો ઍક્સેસ: %1$s\n%2$s ઍક્સેસ\nઅવધિ: %3$s + છેલ્લો ઍક્સેસ: %1$s\n%2$s ઍક્સેસ\nઅવધિ: %3$s + + + છેલ્લો ઍક્સેસ: %1$s\n%2$s ઍક્સેસ (બૅકગ્રાઉન્ડમાં %3$s)\nઅવધિ: %3$s + છેલ્લો ઍક્સેસ: %1$s\n%2$s ઍક્સેસ (બૅકગ્રાઉન્ડમાં %3$s)\nઅવધિ: %3$s + "કોઈપણ પરવાનગી" "ગમે ત્યારે" "છેલ્લા 7 દિવસ" @@ -135,6 +150,7 @@ "%1$sએ તમારા %2$sનો ઍક્સેસ મેળવ્યો નથી." "પરવાનગીઓનો વિગતવાર ઉપયોગ જુઓ" "છેલ્લે થયેલો ઍક્સેસ: %1$s" + "ક્યારેય ઍક્સેસ કરેલ નથી" "મંજૂર" "માત્ર ઉપયોગમાં હોય ત્યારે જ મંજૂરી છે" "નકારેલ" diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml index 61927d1ad..9134ac3aa 100644 --- a/res/values-hi/strings.xml +++ b/res/values-hi/strings.xml @@ -39,6 +39,8 @@ "तभी मंज़ूरी दें जब ऐप्लिकेशन का इस्तेमाल हो रहा हो" "ऐप्लिकेशन" "ऐप्लिकेशन की अनुमतियां" + + "दोबारा न पूछें" "किसी अनुमति की ज़रूरत नहीं है" "दूसरी अनुमतियां" @@ -51,7 +53,8 @@ "ऐसी कार्रवाई करें जिसकी जानकारी नहीं है" "%2$d में से %1$d ऐप्लिकेशन को अनुमति मिली है" "हाल ही में इस्तेमाल हुईं अनुमतियां" - "जानकारी देखें" + + "सिस्टम के ऐप्लिकेशन दिखाएं" "सिस्टम के ऐप्लिकेशन छिपाएं" "किसी ऐप्लिकेशन को इस अनुमति की ज़रूरत नहीं है" @@ -90,9 +93,12 @@ "मौजूदा अनुमतियां" "ऐप्लिकेशन तैयार किया जा रहा है…" "ऐप्लिकेशन के बारे में कोई जानकारी नहीं है" - "अनुमतियों का इस्तेमाल" - "आखिरी बार एक्सेस: %1$s\n%2$s बार एक्सेस किया गया" - "आखिरी बार एक्सेस: %1$s\n%2$s बार एक्सेस किया गया (बैकग्राउंड में %3$s)" + + + + + + "कोई भी अनुमति" "किसी भी समय" "पिछले सात दिनों में" @@ -135,6 +141,8 @@ "%1$s ने आपसे %2$s नहीं ली है." "अनुमतियों के इस्तेमाल से जुड़ी ज़्यादा जानकारी देखें" "पिछली बार एक्सेस किया गया: %1$s" + + "अनुमति है" "सिर्फ़ इस्तेमाल में होने पर अनुमति है" "मंज़ूरी नहीं मिली" @@ -168,16 +176,11 @@ "खोलें" "अनइंस्टॉल करें" "ज़बरदस्ती रोकें" - - - - - - - - - - + "सेटिंग" + "%s को आपके डिवाइस पर पूरा एक्सेस मिला है" + "%s सुलभता सुविधाओं को आपके डिवाइस पर पूरा एक्सेस मिला है" + "%s आपकी स्क्रीन, कार्रवाइयां, और इनपुट देख सकता है और आपके लिए काम कर सकता है. साथ ही, यह स्क्रीन के डिसप्ले को नियंत्रित भी कर सकता है." + "ये सुविधाएं आपकी स्क्रीन, कार्रवाइयां, और इनपुट देख सकती हैं और आपके लिए काम कर सकती हैं. साथ ही, ये स्क्रीन के डिसप्ले को नियंत्रित भी कर सकती हैं." "डिफ़ॉल्ट ऐप्लिकेशन" "कोई डिफ़ॉल्ट ऐप्लिकेशन नहीं." "काम के लिए डिफ़ॉल्ट" @@ -199,11 +202,9 @@ "कॉल की स्क्रीनिंग का ऐप्लिकेशन" "कॉल करने का साथी ऐप्लिकेशन" "कार प्रोजेक्शन ऐप्लिकेशन" - - + "वर्क प्रोफ़ाइल का इस्तेमाल नहीं किया जा सकता" "ध्यान दें : अगर डिवाइस को रीस्टार्ट करते समय उसकी स्क्रीन लॉक है, तो यह ऐप्लिकेशन तब तक शुरू नहीं होगा, जब तक आप डिवाइस को अनलॉक नहीं करते." - - + "Assistant आपके सिस्टम पर इस्तेमाल किए जा रहे ऐप्लिकेशन की जानकारी देख पाएगी. इसमें आपकी स्क्रीन पर दिखाई देने वाली या ऐप्लिकेशन की एक्सेस करने लायक जानकारी शामिल होगी." "डीबग करने की प्रक्रिया का डेटा शेयर करें" "डीबग करने की ज़्यादा जानकारी शेयर करना चाहते हैं?" "%1$s डीबग करने की जानकारी अपलोड करना चाहता है." diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml index a47153a0c..dbb7db330 100644 --- a/res/values-hr/strings.xml +++ b/res/values-hr/strings.xml @@ -39,6 +39,7 @@ "Dopusti samo dok je aplikacija u upotrebi" "Aplikacije" "Dopuštenja aplikacije" + "Upravitelj dopuštenja" "Više me ne pitaj" "Nema dopuštenja" "Dodatna dopuštenja" @@ -52,7 +53,7 @@ "izvršiti nepoznatu radnju" "Aplikacije s dopuštenjem: %1$d od %2$d" "Nedavna upotreba" - "Prikaži pojedinosti" + "Prikaz nadzorne ploče s dopuštenjima" "Prikaži sustav" "Sakrij sustav" "Nema aplikacija" @@ -91,9 +92,27 @@ "Trenutačna dopuštenja" "Postavljanje aplikacije…" "Nepoznato" - "Upotreba dopuštenja" - "Zadnji pristup: %1$s\n%2$s pristup(a)" - "Zadnji pristup: %1$s\n%2$s pristupa (%3$s u pozadini)" + "Nadzorna ploča" + + Zadnji pristup: %1$s\n%2$s pristup + Zadnji pristup: %1$s\n%2$s pristupa + Zadnji pristup: %1$s\n%2$s pristupa + + + Zadnji pristup: %1$s\n%2$s pristup (%3$s u pozadini) + Zadnji pristup: %1$s\n%2$s pristupa (%3$s u pozadini) + Zadnji pristup: %1$s\n%2$s pristupa (%3$s u pozadini) + + + Zadnji pristup: %1$s\n%2$s pristup\nTrajanje: %3$s + Zadnji pristup: %1$s\n%2$s pristupa\nTrajanje: %3$s + Zadnji pristup: %1$s\n%2$s pristupa\nTrajanje: %3$s + + + Zadnji pristup: %1$s\n%2$s pristupa (%3$s u pozadini)\nTrajanje: %3$s + Zadnji pristup: %1$s\n%2$s pristupa (%3$s u pozadini)\nTrajanje: %3$s + Zadnji pristup: %1$s\n%2$s pristupa (%3$s u pozadini)\nTrajanje: %3$s + "Bilo koje dopuštenje" "Bilo kad" "Posljednjih tjedan dana" @@ -136,6 +155,7 @@ "Aplikacija %1$s nije pristupila vašem dopuštenju %2$s." "Pregledajte detaljnu upotrebu dopuštenja" "Zadnji pristup: %1$s" + "Bez pristupa" "Dopušteno" "Dopušteno samo tijekom upotrebe" "Odbijeno" diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml index 26ea52b79..7f136bef6 100644 --- a/res/values-hu/strings.xml +++ b/res/values-hu/strings.xml @@ -39,6 +39,7 @@ "Csak akkor engedélyezett, ha az alkalmazás használatban van" "Alkalmazások" "Alkalmazásengedélyek" + "Engedélykezelő" "Ne jelenjen meg többé" "Nincs engedély" "További engedélyek" @@ -51,7 +52,7 @@ "végrehajt egy ismeretlen műveletet" "%2$d/%1$d alkalmazás kapott engedélyt" "Legutóbbi használat" - "Részletek megtekintése" + "Az engedélyek irányítópultja" "Rendszer megjelenítése" "Rendszer elrejtése" "Nincsenek alkalmazások" @@ -90,9 +91,23 @@ "Jelenlegi engedélyek" "Alkalmazás fokozatos közzététele…" "Ismeretlen" - "Engedélyhasználat" - "Legutóbbi hozzáférés: %1$s\n%2$s hozzáférés" - "Legutóbbi hozzáférés: %1$s\n%2$s hozzáférés (%3$s a háttérben)" + "Irányítópult" + + Legutóbbi hozzáférés: %1$s\n%2$s hozzáférés + Legutóbbi hozzáférés: %1$s\n%2$s hozzáférés + + + Legutóbbi hozzáférés: %1$s\n%2$s hozzáférés (%3$s a háttérben) + Legutóbbi hozzáférés: %1$s\n%2$s hozzáférés (%3$s a háttérben) + + + Legutóbbi hozzáférés: %1$s\n%2$s hozzáférés\nIdőtartam: %3$s + Legutóbbi hozzáférés: %1$s\n%2$s hozzáférés\nIdőtartam: %3$s + + + Legutóbbi hozzáférés: %1$s\n%2$s hozzáférés (%3$s a háttérben)\nIdőtartam: %3$s + Legutóbbi hozzáférés: %1$s\n%2$s hozzáférés (%3$s a háttérben)\nIdőtartam: %3$s + "Bármely engedély" "Bármikor" "Elmúlt 7 nap" @@ -135,6 +150,7 @@ "A(z) %1$s még nem fért hozzá a következő engedélyhez: %2$s." "Engedélyhasználat részletes adatainak megtekintése" "Legutóbbi hozzáférés: %1$s" + "Sosem használta" "Engedélyezett" "Csak használat közben engedélyezett" "Elutasítva" diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml index 24360946d..7e8500380 100644 --- a/res/values-hy/strings.xml +++ b/res/values-hy/strings.xml @@ -39,6 +39,7 @@ "Թույլատրել, միայն երբ հավելվածն օգտագործվում է" "Հավելվածներ" "Հավելվածների թույլտվություններ" + "Թույլտվությունների կառավարիչ" "Այլևս չհարցնել" "Թույլտվություններ չկան" "Լրացուցիչ թույլտվություններ" @@ -51,7 +52,7 @@ "կատարել անհայտ գործողություն" "Թույլատրված է %1$d հավելված՝ %2$d-ից" "Վերջին օգտագործումը" - "Մանրամասն" + "Թույլտվությունների վահանակ" "Ցույց տալ համակարգի հավելվածները" "Թաքցնել համակարգի հավելվածները" "Հավելվածներ չկան" @@ -90,9 +91,23 @@ "Ընթացիկ թույլտվություններ" "Սպասեք…" "Անհայտ" - "Թույլտվությունների օգտագործում" - "Վերջին օգտագործումը՝ Օգտագործվել է %1$s\n%2$s անգամ" - "Վերջին օգտագործումը՝ Օգտագործվել է %1$s\n%2$s անգամ (%3$s անգամ ֆոնային ռեժիմում)" + "Կառավարման վահանակ" + + Վերջին օգտագործումը՝ %1$s\n%2$s անգամ + Վերջին օգտագործումը՝ %1$s\n%2$s անգամ + + + Վերջին օգտագործումը՝ %1$s\n%2$s անգամ (%3$s անգամ ֆոնային ռեժիմում) + Վերջին օգտագործումը՝ %1$s\n%2$s անգամ (%3$s անգամ ֆոնային ռեժիմում) + + + Վերջին օգտագործումը՝ %1$s\n%2$s անգամ\nՏևողությունը՝ %3$s + Վերջին օգտագործումը՝ %1$s\n%2$s անգամ\nՏևողությունը՝ %3$s + + + Վերջին օգտագործումը՝ %1$s\n%2$s անգամ (%3$s անգամ ֆոնային ռեժիմում)\nՏևողությունը՝ %3$s + Վերջին օգտագործումը՝ %1$s\n%2$s անգամ (%3$s անգամ ֆոնային ռեժիմում)\nՏևողությունը՝ %3$s + "Բոլոր թույլտվությունները" "Ցանկացած ժամանակ" "Վերջին 7 օրում" @@ -135,6 +150,7 @@ "%1$s հավելվածին հասանելի չէ ձեր %2$sը:" "Դիտել թույլտվությունների օգտագործման մանրամասները" "Վերջին օգտագործումը՝ %1$s" + "Երբեք չի օգտագործվել" "Թույլատրված" "Միայն հավելվածն օգտագործելիս" "Մերժված" diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml index 03ae84a10..e74269593 100644 --- a/res/values-in/strings.xml +++ b/res/values-in/strings.xml @@ -39,6 +39,7 @@ "Izinkan hanya saat aplikasi sedang digunakan" "Aplikasi" "Izin aplikasi" + "Pengelola izin" "Jangan tanya lagi" "Tidak ada izin" "Izin tambahan" @@ -51,7 +52,7 @@ "melakukan tindakan yang tidak dikenal" "%1$d dari %2$d aplikasi diizinkan" "Penggunaan terbaru" - "Lihat detail" + "Lihat Dasbor Izin" "Tampilkan sistem" "Sembunyikan sistem" "Tidak ada aplikasi" @@ -90,9 +91,23 @@ "Izin saat ini" "Menyiapkan aplikasi..." "Tidak tahu" - "Penggunaan izin" - "Akses terakhir: %1$s\n%2$s akses" - "Akses terakhir: %1$s\n%2$s akses (%3$s di latar belakang)" + "Dasbor" + + Akses terakhir: Akses %1$s\n%2$s + Akses terakhir: Akses %1$s\n%2$s + + + Akses terakhir: Akses %1$s\n%2$s (%3$s di latar belakang) + Akses terakhir: Akses %1$s\n%2$s (%3$s di latar belakang) + + + Akses terakhir: Akses %1$s\n%2$s \nDurasi: %3$s + Akses terakhir: Akses %1$s\n%2$s \nDurasi: %3$s + + + Akses terakhir: Akses %1$s\n%2$s (%3$s di latar belakang)\nDurasi: %3$s + Akses terakhir: Akses %1$s\n%2$s (%3$s di latar belakang)\nDurasi: %3$s + "Izin apa pun" "Kapan saja" "7 hari terakhir" @@ -135,6 +150,7 @@ "%1$s belum mengakses %2$s Anda." "Melihat penggunaan izin mendetail" "Akses terakhir: %1$s" + "Tidak pernah mengakses" "Diizinkan" "Hanya diizinkan saat digunakan" "Ditolak" diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml index 1870106be..8b053a7f3 100644 --- a/res/values-is/strings.xml +++ b/res/values-is/strings.xml @@ -39,6 +39,7 @@ "Leyfa aðeins þegar forritið er í notkun" "Forrit" "Heimildir forrits" + "Heimildastjóri" "Ekki spyrja aftur" "Engar heimildir" "Viðbótarheimildir" @@ -51,7 +52,7 @@ "framkvæma óþekkta aðgerð" "%1$d af %2$d forritum leyfð" "Nýleg notkun" - "Skoða upplýsingar" + "Skoða stjórnborð heimilda" "Sýna kerfi" "Fela kerfi" "Engin forrit" @@ -90,9 +91,23 @@ "Núgildandi heimildir" "Setur upp forrit…" "Óþekkt" - "Heimildanotkun" - "Síðast notuð: %1$s\n Notuð %2$s sinnum" - "Síðast notuð: %1$s\n Notuð %2$s sinnum (%3$s sinnum í bakgrunni)" + "Stjórnborð" + + Síðast notuð: %1$s\n Notuð %2$s sinni + Síðast notuð: %1$s\n Notuð %2$s sinnum + + + Síðast notuð: %1$s\n Notuð %2$s sinni (%3$s sinni í bakgrunni) + Síðast notuð: %1$s\n Notuð %2$s sinnum (%3$s sinnum í bakgrunni) + + + Síðast notuð: %1$s\n Notuð %2$s sinni\nLengd: %3$s + Síðast notuð: %1$s\n Notuð %2$s sinni\nLengd: %3$s + + + Síðast notuð: %1$s\n Notuð %2$s sinni (%3$s sinni í bakgrunni)\nLengd: %3$s + Síðast notuð: %1$s\n Notuð %2$s sinnum (%3$s sinnum í bakgrunni)\nLengd: %3$s + "Hvaða heimild sem er" "Hvenær sem er" "Síðustu sjö daga" @@ -135,6 +150,7 @@ "%1$s hefur ekki fengið aðgang að %2$s." "Skoða nákvæma heimildanotkun" "Síðast notuð: %1$s" + "Aldrei notuð" "Leyft" "Aðeins leyft við notkun" "Hafnað" diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml index 2a65ee473..df7c79d90 100644 --- a/res/values-it/strings.xml +++ b/res/values-it/strings.xml @@ -39,6 +39,7 @@ "Consenti solo mentre l\'app è in uso" "App" "Autorizzazioni app" + "Gestione autorizzazioni" "Non chiedermelo più" "Nessuna autorizzazione" "Altre autorizzazioni" @@ -51,7 +52,7 @@ "esegue un\'azione sconosciuta" "Sono consentite %1$d app su %2$d" "Utilizzo recente" - "Vedi i dettagli" + "Dashboard autorizzazioni" "Mostra sistema" "Nascondi sistema" "Nessuna app" @@ -90,9 +91,23 @@ "Autorizzazioni correnti" "App in preparazione…" "Sconosciuto" - "Uso delle autorizzazioni" - "Ultimo accesso: %1$s\n%2$s accessi" - "Ultimo accesso: %1$s\n%2$s accessi (%3$s in background)" + "Dashboard" + + Ultimo accesso: %1$s\n%2$s accessi + Ultimo accesso: %1$s\n%2$s accesso + + + Ultimo accesso: %1$s\n%2$s accessi (%3$s in background) + Ultimo accesso: %1$s\n%2$s accesso (%3$s in background) + + + Ultimo accesso: %1$s\n%2$s accessi\nDurata: %3$s + Ultimo accesso: %1$s\n%2$s accesso\nDurata: %3$s + + + Ultimo accesso: %1$s\n%2$s accessi (%3$s in background)\nDurata: %3$s + Ultimo accesso: %1$s\n%2$s accesso (%3$s in background)\nDurata: %3$s + "Qualsiasi autorizzazione" "Qualsiasi data" "Ultimi 7 giorni" @@ -135,6 +150,7 @@ "%1$s non ha accesso a %2$s." "Consulta l\'uso dettagliato delle autorizzazioni" "Ultimo accesso: %1$s" + "Accesso mai eseguito" "Consentite" "Consentite solo durante l\'uso" "Rifiutate" diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml index 8bbc4f41c..789e740f9 100644 --- a/res/values-iw/strings.xml +++ b/res/values-iw/strings.xml @@ -39,6 +39,7 @@ "לאישור רק בזמן שהאפליקציה בשימוש" "אפליקציות" "הרשאות לאפליקציה" + "מנהל הרשאות" "אל תשאל שוב" "אין הרשאות" "הרשאות נוספות" @@ -53,7 +54,7 @@ "ביצוע פעולה לא ידועה" "%1$d מתוך %2$d אפליקציות קיבלו הרשאה" "נתוני שימוש אחרונים בהרשאות" - "הצגת פרטים" + "למרכז השליטה של ההרשאות" "הצגת המערכת" "הסתרת המערכת" "אין אפליקציות" @@ -92,9 +93,31 @@ "הרשאות קיימות" "מכין אפליקציה להתקנה…" "לא ידוע" - "שימוש בהרשאות" - "גישה אחרונה: %1$s\n%2$s קבלות גישה" - "גישה אחרונה: %1$s\n%2$s קבלות גישה (%3$s ברקע)" + "מרכז שליטה" + + גישה אחרונה: %1$s\n%2$s קבלות גישה + גישה אחרונה: %1$s\n%2$s קבלות גישה + גישה אחרונה: %1$s\n%2$s קבלות גישה + גישה אחרונה: %1$s\nגישה אחת (%2$s) + + + גישה אחרונה: %1$s\n%2$s קבלות גישה (%3$s ברקע) + גישה אחרונה: %1$s\n%2$s קבלות גישה (%3$s ברקע) + גישה אחרונה: %1$s\n%2$s קבלות גישה (%3$s ברקע) + גישה אחרונה: %1$s\nגישה אחת (%2$s, %3$s ברקע) + + + גישה אחרונה: %1$s\n%2$s קבלות גישה\nמשך הזמן: %3$s + גישה אחרונה: %1$s\n%2$s קבלות גישה\nמשך הזמן: %3$s + גישה אחרונה: %1$s\n%2$s קבלות גישה\nמשך הזמן: %3$s + גישה אחרונה: %1$s\nגישה אחת (%2$s)\nמשך הזמן: %3$s + + + גישה אחרונה: %1$s\n%2$s קבלות גישה (%3$s ברקע)\nמשך הזמן: %3$s + גישה אחרונה: %1$s\n%2$s קבלות גישה (%3$s ברקע)\nמשך הזמן: %3$s + גישה אחרונה: %1$s\n%2$s קבלות גישה (%3$s ברקע)\nמשך הזמן: %3$s + גישה אחרונה: %1$s\nגישה אחת (%2$s, %3$s ברקע)\nמשך הזמן: %3$s + "כל הרשאה שהיא" "בכל עת" "7 הימים האחרונים" @@ -137,6 +160,7 @@ "לאפליקציה %1$s לא הייתה גישה אל %2$s." "הצגת שימוש מפורט בהרשאות" "גישה אחרונה: %1$s" + "אף פעם לא בוצעה גישה" "יש הרשאה" "מורשית רק בזמן שימוש" "אין הרשאה" diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml index cd0307402..1826158d8 100644 --- a/res/values-ja/strings.xml +++ b/res/values-ja/strings.xml @@ -39,6 +39,7 @@ "アプリが使用中の場合のみ許可" "アプリ" "アプリの権限" + "権限マネージャ" "今後表示しない" "権限がありません" "その他の権限" @@ -51,7 +52,7 @@ "不明な操作の実行" "%1$d/%2$d 個のアプリを許可" "最近の使用状況" - "詳細を表示" + "権限ダッシュボードを表示" "システムを表示" "システムを表示しない" "アプリがありません" @@ -90,9 +91,23 @@ "現在の権限" "アプリを準備しています…" "不明" - "権限の使用" - "前回のアクセス: %1$s\nアクセス数 %2$s 回" - "前回のアクセス: %1$s\nアクセス数 %2$s 回(バックグラウンドで %3$s 回)" + "ダッシュボード" + + 前回のアクセス: %1$s\nアクセス回数: %2$s + 前回のアクセス: %1$s\nアクセス回数: %2$s + + + 前回のアクセス: %1$s\nアクセス数: %2$s 回(バックグラウンドで %3$s 回) + 前回のアクセス: %1$s\nアクセス数: %2$s 回(バックグラウンドで %3$s 回) + + + 前回のアクセス: %1$s\nアクセス回数: %2$s 回\n時間: %3$s + 前回のアクセス: %1$s\nアクセス回数: %2$s 回\n時間: %3$s + + + 前回のアクセス: %1$s\nアクセス回数: %2$s 回(バックグラウンドで %3$s 回)\n時間: %3$s + 前回のアクセス: %1$s\nアクセス回数: %2$s 回(バックグラウンドで %3$s 回)\n時間: %3$s + "すべての権限" "全期間" "過去 7 日間" @@ -135,6 +150,7 @@ "%1$s はユーザーの%2$sにはアクセスしていません。" "権限の使用に関する詳細を表示" "前回のアクセス: %1$s" + "未アクセス" "許可" "使用中のみ許可" "拒否" diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml index 8c414d0ab..80548a203 100644 --- a/res/values-ka/strings.xml +++ b/res/values-ka/strings.xml @@ -39,6 +39,7 @@ "მხოლოდ აპის გამოყენებისას დაშვება" "აპები" "აპის ნებართვები" + "ნებართვების მმართველი" "აღარ მკითხო" "ნებართვები არ არის" "დამატებითი ნებართვები" @@ -51,7 +52,7 @@ "უცნობი ქმედების შესრულება" "დაშვებულია %1$d/%2$d აპიდან" "ბოლოდროინდელი გამოყენება" - "დეტალების ნახვა" + "ნებართვის საინფ. დაფის ნახვა" "სისტემის ჩვენება" "სისტემური პროცესების დამალვა" "აპები არ არის" @@ -90,9 +91,23 @@ "ამჟამინდელი ნებართვები" "მიმდინარეობს აპის შუალედური შენახვა…" "უცნობი" - "ნებართვებით სარგებლობა" - "ბოლო წვდომა: %1$s\n%2$s წვდომა" - "ბოლო წვდომა: %1$s\n%2$s წვდომა (%3$s ფონურ რეჟიმში)" + "საინფორმაციო დაფა" + + ბოლო წვდომა: %1$s\n%2$s წვდომა + ბოლო წვდომა: %1$s\n%2$s წვდომა + + + ბოლო წვდომა: %1$s\n%2$s წვდომა (%3$s ფონურ რეჟიმში) + ბოლო წვდომა: %1$s\n%2$s წვდომა (%3$s ფონურ რეჟიმში) + + + ბოლო წვდომა: %1$s\n%2$s წვდომა\nხანგრძლივობა: %3$s + ბოლო წვდომა: %1$s\n%2$s წვდომა\nხანგრძლივობა: %3$s + + + ბოლო წვდომა: %1$s\n%2$s წვდომა (%3$s ფონურ რეჟიმში)\nხანგრძლივობა: %3$s + ბოლო წვდომა: %1$s\n%2$s წვდომა (%3$s ფონურ რეჟიმში)\nხანგრძლივობა: %3$s + "ნებისმიერი ნებართვა" "ნებისმიერი დრო" "ბოლო 7 დღე" @@ -135,6 +150,7 @@ "%1$s-ს არ გამოუყენებია თქვენი %2$s." "ნებართვების გამოყენების დეტალურად ნახვა" "ბოლო წვდომა: %1$s" + "არ ჰქონია წვდომა" "დაშვებულია" "დაშვებულია მხოლოდ გამოყენებისას" "უარყოფილია" diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml index 879e6e393..fa8333ada 100644 --- a/res/values-kk/strings.xml +++ b/res/values-kk/strings.xml @@ -39,6 +39,7 @@ "Қолданба пайдаланылып жатқанда ғана рұқсат беру" "Қолданбалар" "Қолданба рұқсаттары" + "Рұқсат басқарушысы" "Қайта сұралмасын" "Рұқсат жоқ" "Қосымша рұқсаттар" @@ -51,7 +52,7 @@ "белгісіз әрекетті орындау" "%1$d/%2$d қолданба рұқсатқа ие" "Соңғы рет пайдаланылуы" - "Мәліметтерді көру" + "Рұқсаттар бақылау тақтасын көру" "Жүйені көрсету" "Жүйені жасыру" "Қолданбалар жоқ" @@ -90,9 +91,23 @@ "Ағымдағы рұқсаттар" "Қолданба реттелуде…" "Белгісіз" - "Рұқсаттарды пайдалану" - "Соңғы рет пайдаланылған уақыты: %1$s\n%2$s рет пайдаланылды" - "Соңғы рет пайдаланылған уақыты: %1$s\n%2$s рет пайдаланылды (фондық режимде %3$s рет)" + "Бақылау тақтасы" + + Соңғы рет пайдаланылды: %1$s\n%2$s рет + Соңғы рет пайдаланылды: %1$s\n%2$s рет + + + Соңғы рет пайдаланылды: %1$s\n%2$s рет (фондық режимде %3$s рет) + Соңғы рет пайдаланылды: %1$s\n%2$s рет (фондық режимде %3$s рет) + + + Соңғы рет пайдаланылды: %1$s\n%2$s рет\nҰзақтығы: %3$s + Соңғы рет пайдаланылды: %1$s\n%2$s рет\nҰзақтығы: %3$s + + + Соңғы рет пайдаланылды: %1$s\n%2$s рет (фондық режимде %3$s рет)\nҰзақтығы: %3$s + Соңғы рет пайдаланылды: %1$s\n%2$s рет (фондық режимде %3$s рет)\nҰзақтығы: %3$s + "Кез келген рұқсат" "Кез келген уақытта" "Соңғы 7 күн" @@ -135,6 +150,7 @@ "%1$s қолданбасы %2$s рұқсатын пайдаланбады." "Рұқсаттардың пайдаланылуы туралы мәліметтерді көру" "Соңғы рет пайдаланылған уақыт: %1$s" + "Ешқашан пайдаланылмады" "Берілген рұқсаттар" "Қолданылып жатқанда ғана рұқсат етіледі" "Тыйым салынғандар" @@ -168,16 +184,11 @@ "Ашу" "Жою" "Қолмен тоқтату" - - - - - - - - - - + "Параметрлер" + "%s қызметі құрылғыңызды толықтай пайдалана алады" + "Арнайы мүмкіндіктер ұсынатын %s қызмет құрылғыңызды толықтай пайдалана алады" + "%s сіздің экраныңызды, әрекеттеріңізді және енгізген деректеріңізді көре алады, әрекеттерді орындап, дисплейді басқара алады." + "Бұл қызметтер сіздің экраныңызды, әрекеттеріңізді және енгізген деректеріңізді көре алады, әрекеттерді орындап, дисплейді басқара алады." "Әдепкі қолданбалар" "Әдепкі қолданбалар жоқ" "Жұмыс үшін әдепкі қолданба" @@ -199,11 +210,9 @@ "Қоңырауды тексеру қолданбасы" "Қоңырауға арналған қосымша қолданба" "Көлік экранына шығару" - - + "Жұмыс профиліне қолдау көрсетпейді." "Ескертпе: Құрылғыңызды қайта қоссаңыз және экран құлыпталса, құрылғының құлпы ашылмайынша, қолданба іске қосылмайды." - - + "Көмекші қолданба жүйеде пайдаланылып жатқан қолданбалар туралы ақпаратты, соның ішінде экранға шығатын немесе қолданбалардағы деректерді оқи алады." "Түзету туралы деректерді бөлісу" "Түзету туралы толығырақ деректер бөлісілсін бе?" "%1$s қолданбасы түзету туралы ақпаратты жүктеп салғысы келеді." diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml index a7cc91ccf..716712b9c 100644 --- a/res/values-km/strings.xml +++ b/res/values-km/strings.xml @@ -39,6 +39,7 @@ "អនុញ្ញាត​ពេល​កំពុង​ប្រើប្រាស់​កម្មវិធីតែ​ប៉ុណ្ណោះ" "កម្មវិធី" "ការអនុញ្ញាតកម្មវិធី" + "កម្មវិធីគ្រប់គ្រង​ការអនុញ្ញាត" "កុំសួរ​ម្ដងទៀត" "គ្មានការអនុញ្ញាតទេ" "ការអនុញ្ញាតបន្ថែម" @@ -51,7 +52,7 @@ "ប្រតិបត្តិការសកម្មភាពមិនស្គាល់" "បានអនុញ្ញាត​កម្មវិធី %1$d ក្នុងចំណោម​ %2$d" "ការប្រើប្រាស់ថ្មីៗ" - "មើល​ព័ត៌មាន​លម្អិត" + "មើល​ផ្ទាំងគ្រប់គ្រង​ការអនុញ្ញាត" "បង្ហាញ​ប្រព័ន្ធ" "លាក់ប្រព័ន្ធ" "គ្មានកម្មវិធី" @@ -90,9 +91,23 @@ "ការអនុញ្ញាត​បច្ចុប្បន្ន" "កំពុងសាកល្បងកម្មវិធី…" "មិនស្គាល់" - "ការប្រើប្រាស់​ការអនុញ្ញាត" - "ការចូលប្រើ​ចុងក្រោយ៖ %1$s\nការចូលប្រើ %2$s ដង" - "ការចូលប្រើ​ចុងក្រោយ៖ %1$s\nការចូលប្រើ %2$s ដង (%3$s នៅផ្ទៃ​ខាងក្រោយ)" + "ផ្ទាំង​គ្រប់គ្រង" + + ការចូលប្រើ​ចុងក្រោយ៖ %1$s\nការចូលប្រើ %2$s ដង + ការចូលប្រើ​ចុងក្រោយ៖ %1$s\nការចូលប្រើ %2$s ដង + + + ការចូលប្រើ​ចុងក្រោយ៖ %1$s\nការចូលប្រើ %2$s ដង (%3$s ដងនៅផ្ទៃខាងក្រោយ) + ការចូលប្រើ​ចុងក្រោយ៖ %1$s\nការចូលប្រើ %2$s ដង (%3$s ដងនៅផ្ទៃខាងក្រោយ) + + + ការចូលប្រើចុងក្រោយ៖ %1$s\nការចូលប្រើ %2$s ដង\nរយៈពេល៖ %3$s + ការចូលប្រើ​ចុងក្រោយ៖ %1$s\nការចូលប្រើ %2$s ដង\nរយៈពេល៖ %3$s + + + ការចូលប្រើ​ចុងក្រោយ៖ %1$s\nការចូលប្រើ %2$s ដង (%3$s ដងនៅផ្ទៃខាងក្រោយ)\nរយៈពេល៖ %3$s + ការចូលប្រើ​ចុងក្រោយ៖ %1$s\nការចូលប្រើ %2$s ដង (%3$s ដងនៅផ្ទៃខាងក្រោយ)\nរយៈពេល៖ %3$s + "ការអនុញ្ញាត​ណាមួយ" "ពេល​ណា​ក៏​បាន" "7 ថ្ងៃ​ចុងក្រោយ" @@ -135,6 +150,7 @@ "%1$s មិន​បាន​ចូលប្រើ %2$s របស់អ្នក​ទេ។" "មើល​ការ​ប្រើប្រាស់​ការអនុញ្ញាត​លម្អិត" "ការចូលប្រើ​ចុងក្រោយ៖ %1$s" + "មិនធ្លាប់​ចូលប្រើ" "បាន​អនុញ្ញាត" "អនុញ្ញាត​ខណៈពេល​ប្រើប្រាស់តែ​ប៉ុណ្ណោះ" "បានបដិសេធ" @@ -168,16 +184,11 @@ "បើក" "លុប" "បង្ខំ​ឱ្យ​បញ្ឈប់" - - - - - - - - - - + "ការកំណត់" + "%s មានសិទ្ធិ​ពេញលេញ​ក្នុងការ​ចូលប្រើ​ឧបករណ៍​របស់អ្នក" + "សេវាកម្ម​ភាពងាយស្រួល %s មានសិទ្ធិ​ពេញលេញ​ក្នុងការ​ចូលប្រើ​ឧបករណ៍​របស់អ្នក" + "%s អាចមើល​អេក្រង់ សកម្មភាព និង​ការវាយបញ្ចូល​របស់អ្នក ធ្វើ​សកម្មភាព និង​គ្រប់គ្រង​ផ្ទាំងអេក្រង់​បាន។" + "សេវាកម្ម​ទាំងនេះ​អាចមើល​អេក្រង់ សកម្មភាព និង​ការវាយបញ្ចូល​របស់អ្នក ធ្វើ​សកម្មភាព និង​គ្រប់គ្រង​ផ្ទាំងអេក្រង់​បាន។" "កម្មវិធី​លំនាំដើម" "គ្មានកម្មវិធីលំនាំដើមទេ" "លំនាំដើម​សម្រាប់ការងារ" @@ -199,11 +210,9 @@ "កម្មវិធីត្រួតពិនិត្យការហៅទូរសព្ទ" "កម្មវិធី​ដៃគូ​សម្រាប់​ហៅទូរសព្ទ" "កម្មវិធី​បញ្ចាំង​របស់​រថយន្ត" - - + "មិនស្គាល់​កម្រងព័ត៌មាន​ការងារ​ទេ" "ចំណាំ៖ ប្រសិនបើ​អ្នកចាប់ផ្ដើម​ឧបករណ៍​​របស់អ្នក​ឡើងវិញ និងបានកំណត់​ការចាក់សោ​អេក្រង់ កម្មវិធីនេះ​មិនអាច​ចាប់ផ្តើម​បានទេ រហូតទាល់តែ​អ្នកដោះសោ​ឧបករណ៍របស់អ្នក។" - - + "ជំនួយការនឹងអាចអានព័ត៌មានអំពីកម្មវិធីដែលកំពុងប្រើនៅក្នុងប្រព័ន្ធរបស់អ្នក រួម​ទាំងព័ត៌មានដែលអាចមើលឃើញនៅលើអេក្រង់របស់អ្នក ឬព័ត៌មានដែលអាចចូលប្រើនៅក្នុងកម្មវិធី​នោះផងដែរ​។" "ចែករំលែក​ទិន្នន័យ​នៃការ​ជួសជុល" "ចែករំលែក​ទិន្នន័យ​លម្អិត​នៃការជួសជុល?" "%1$s ចង់​បង្ហោះ​ព័ត៌មាននៃ​ការជួសជុល។" diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml index 2c454bff3..4ffd879ee 100644 --- a/res/values-kn/strings.xml +++ b/res/values-kn/strings.xml @@ -39,6 +39,7 @@ "ಆ್ಯಪ್ ಬಳಕೆಯಲ್ಲಿದ್ದಾಗ ಮಾತ್ರ ಅನುಮತಿಸಿ" "ಆ್ಯಪ್‌ಗಳು" "ಆ್ಯಪ್ ಅನುಮತಿಗಳು" + "ಅನುಮತಿ ನಿರ್ವಾಹಕರು" "ಮತ್ತೆ ಕೇಳಬೇಡಿ" "ಯಾವುದೇ ಅನುಮತಿಗಳಿಲ್ಲ" "ಹೆಚ್ಚುವರಿ ಅನುಮತಿಗಳು" @@ -51,7 +52,7 @@ "ಅಪರಿಚಿತ ಕ್ರಿಯೆಯನ್ನು ಮಾಡಿ" "%2$d ರಲ್ಲಿ %1$d ಆ್ಯಪ್‌ಗಳನ್ನು ಅನುಮತಿಸಲಾಗಿದೆ" "ಇತ್ತೀ ಚಿನ ಬಳಕೆ" - "ವಿವರಗಳನ್ನು ನೋಡಿ" + "ಅನುಮತಿಗಳ ಡ್ಯಾಶ್‌ಬೋರ್ಡ್ ವೀಕ್ಷಿಸಿ" "ಸಿಸ್ಟಂ ತೋರಿಸಿ" "ಸಿಸ್ಟಂ ಮರೆಮಾಡಿ" "ಯಾವುದೇ ಆ್ಯಪ್‌ಗಳು ಇಲ್ಲ" @@ -90,9 +91,23 @@ "ಪ್ರಸ್ತುತ ಅನುಮತಿಗಳು" "ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಲು ಸಿದ್ಧವಿರುವ ಆ್ಯಪ್…" "ಅಪರಿಚಿತ" - "ಅನುಮತಿಗಳ ಬಳಕೆ" - "ಕೊನೆಯ ಪ್ರವೇಶ: %1$s\n%2$s ಪ್ರವೇಶಗಳು" - "ಕೊನೆಯ ಪ್ರವೇಶ: %1$s\n%2$s ಪ್ರವೇಶಗಳು (ಹಿನ್ನೆಲೆಯಲ್ಲಿ %3$s)" + "ಡ್ಯಾಶ್‌ಬೋರ್ಡ್" + + ಕೊನೆಯ ಪ್ರವೇಶ: %1$s\n%2$s ಪ್ರವೇಶ + ಕೊನೆಯ ಪ್ರವೇಶ: %1$s\n%2$s ಪ್ರವೇಶ + + + ಕೊನೆಯ ಪ್ರವೇಶ: %1$s\n%2$s ಪ್ರವೇಶ (%3$sಹಿನ್ನೆಲೆಯಲ್ಲಿ) + ಕೊನೆಯ ಪ್ರವೇಶ: %1$s\n%2$s ಪ್ರವೇಶ (%3$sಹಿನ್ನೆಲೆಯಲ್ಲಿ) + + + ಕೊನೆಯ ಪ್ರವೇಶ: %1$s\n%2$s ಪ್ರವೇಶ\nಸಮಯ: %3$s + ಕೊನೆಯ ಪ್ರವೇಶ: %1$s\n%2$s ಪ್ರವೇಶ\nಸಮಯ: %3$s + + + ಕೊನೆಯ ಪ್ರವೇಶ: %1$s\n%2$s ಪ್ರವೇಶ (%3$sಹಿನ್ನೆಲೆಯಲ್ಲಿ)\nಸಮಯದಲ್ಲಿ: %3$s + ಕೊನೆಯ ಪ್ರವೇಶ: %1$s\n%2$s ಪ್ರವೇಶ (%3$sಹಿನ್ನೆಲೆಯಲ್ಲಿ)\nಸಮಯದಲ್ಲಿ: %3$s + "ಯಾವುದೇ ಅನುಮತಿ" "ಯಾವುದಾದರೂ ಸಮಯದಲ್ಲಿ" "ಕಳೆದ 7 ದಿನಗಳು" @@ -135,6 +150,7 @@ "%1$s ನಿಮ್ಮ %2$s ಅನ್ನು ಪ್ರವೇಶಿಸಿಲ್ಲ." "ವಿವರವಾದ ಅನುಮತಿಗಳ ಬಳಕೆಯನ್ನು ವೀಕ್ಷಿಸಿ" "ಕೊನೆಯ ಪ್ರವೇಶ:%1$s" + "ಎಂದಿಗೂ ಪ್ರವೇಶಿಸಿಲ್ಲ" "ಅನುಮತಿಸಲಾಗಿದೆ" "ಬಳಕೆಯಲ್ಲಿದ್ದಾಗ ಮಾತ್ರ ಅನುಮತಿಸಲಾಗಿದೆ" "ನಿರಾಕರಿಸಲಾಗಿದೆ" diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml index 9ff2d7fc6..ea7daa131 100644 --- a/res/values-ko/strings.xml +++ b/res/values-ko/strings.xml @@ -39,6 +39,7 @@ "앱 사용 중에만 허용" "앱" "앱 권한" + "권한 관리자" "다시 묻지 않음" "권한 없음" "추가 권한" @@ -51,7 +52,7 @@ "알 수 없는 작업 실행" "%1$d/%2$d개 앱 허용됨" "최근 사용량" - "세부정보 보기" + "권한 대시보드 보기" "시스템 표시" "시스템 숨기기" "앱 없음" @@ -90,9 +91,23 @@ "현재 권한" "앱 준비 중…" "알 수 없음" - "사용 권한" - "마지막 액세스 시간: %1$s\n액세스 %2$s회" - "마지막 액세스 시간: %1$s\n액세스 %2$s회(백그라운드에서 %3$s회)" + "대시보드" + + 마지막 액세스: %1$s\n액세스 %2$s + 마지막 액세스: %1$s\n액세스 %2$s + + + 마지막 액세스: %1$s\n액세스 %2$s회(백그라운드에서 %3$s회) + 마지막 액세스: %1$s\n액세스 %2$s회(백그라운드에서 %3$s회) + + + 마지막 액세스: %1$s\n액세스 %2$s회\n시간: %3$s + 마지막 액세스: %1$s\n액세스 %2$s회\n시간: %3$s + + + 마지막 액세스: %1$s\n액세스 %2$s회(백그라운드에서 %3$s회)\n시간: %3$s + 마지막 액세스: %1$s\n액세스 %2$s회(백그라운드에서 %3$s회)\n시간: %3$s + "모든 권한" "전체 기간" "지난 7일" @@ -135,6 +150,7 @@ "%1$s 앱이 %2$s에 액세스하지 않았습니다." "자세한 권한 사용 내역 보기" "마지막 액세스: %1$s" + "액세스하지 않음" "허용됨" "사용 중에만 허용됨" "거부됨" diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml index 3caaa4ce7..0ffe8c990 100644 --- a/res/values-ky/strings.xml +++ b/res/values-ky/strings.xml @@ -39,6 +39,7 @@ "Колдонмо пайдаланылып жаткан учурда гана уруксат берүү" "Колдонмолор" "Колдонмонун уруксаттары" + "Уруксаттарды башкаргыч" "Экинчи суралбасын" "Уруксаттар жок" "Кошумча уруксаттар" @@ -51,7 +52,7 @@ "белгисиз аракеттерди жасайт" "%2$d колдонмонун ичинен %1$d уруксат берилген" "Акыркы уруксаттардын колдонулушун көрүү" - "Кеңири маалымат" + "Уруксаттардын тактасын көрүү" "Тутумдагы процесстерди көрсөтүү" "Тутумдагы процесстерди жашыруу" "Бир да колдонмо жок" @@ -90,9 +91,23 @@ "Учурдагы уруксаттар" "Күтө туруңуз…" "Белгисиз" - "Уруксаттардын колдонулушу" - "Акыркы жолу колдонулушу: %1$s\n%2$s жолу колдонулду" - "Акыркы жолу колдонулушу: %1$s\n%2$s жолу колдонулду (%3$s фондук режимде" + "Куралдар тактасы" + + Акыркы жолу колдонулушу: %1$s\n%2$s жолу колдонулду + Акыркы жолу колдонулушу: %1$s\n%2$s жолу колдонулду + + + Акыркы жолу колдонулушу: %1$s\n%2$s жолу колдонулду (%3$s фондук режимде) + Акыркы жолу колдонулушу: %1$s\n%2$s жолу колдонулду (%3$s фондук режимде) + + + Акыркы жолу колдонулушу: %1$s\n%2$s жолу колдонулду\nУзактыгы: %3$s + Акыркы жолу колдонулушу: %1$s\n%2$s жолу колдонулду\nУзактыгы: %3$s + + + Акыркы жолу колдонулушу: %1$s\n%2$s жолу колдонулду (%3$s фондук режимде)\nУзактыгы: %3$s + Акыркы жолу колдонулушу: %1$s\n%2$s жолу колдонулду (%3$s фондук режимде)\nУзактыгы: %3$s + "Бардык уруксаттар" "Каалаган убакта" "Акыркы 7 күндө" @@ -135,6 +150,7 @@ "%1$s %2$s уруксаттарыңызга кирген жок." "Уруксаттардын колдонулушун чоо-жайы менен көрүү" "Акыркы жолу колдонулушу: %1$s" + "Эч качан колдонулган эмес" "Уруксат берилген" "Колдонулган кезде гана уруксат" "Четке кагылды" @@ -168,16 +184,11 @@ "Ачуу" "Чыгарып салуу" "Мажбурлап токтотуу" - - - - - - - - - - + "Жөндөөлөр" + "%s кызматынын түзмөгүңүзгө кирүүгө толук мүмкүнчүлүгү бар" + "%s атайын мүмкүнчүлүктөр кызматынын түзмөгүңүзгө кирүүгө толук мүмкүнчүлүгү бар" + "%s экраныңыздагы маалыматты, аракеттерди жана киргизүүлөрдү көрүп, аракеттерди аткарып, дисплейди көзөмөлдөйт." + "Бул кызматтар экраныңыздагы маалыматты, аракеттерди жана киргизүүлөрдү көрүп, аракеттерди аткарып, дисплейди көзөмөлдөйт." "Демейки колдонмолор" "Демейки колдонмолор жок" "Жумуш үчүн демейки жөндөөлөр" @@ -199,11 +210,9 @@ "Чалууларды башкаруу колдонмосу" "Чалууга коштомо колдонмо" "Унааны долбоорлоо колдонмосу" - - + "Жумуш профили колдоого алынбайт" "Эскертүү: Эгер түзмөгүңүздү өчүрүп күйгүзгөндө экранды бөгөттөө жөндөлгөн болсо, түзмөктү бөгөттөн чыгармайынча бул колдонмо ачылбайт." - - + "Жардамчы тутумуңузда иштеп жаткан колдонмолор тууралуу маалыматтарды, анын ичинде экраныңызда көрүнүп турган же колдонмолордо жеткиликтүү болгон маалыматты окуй алат." "Мүчүлүштүктөрдү оңдоо дайындарын бөлүшүү" "Мүчүлүштүктөрдү оңдоо дайындары бөлүшүлсүнбү?" "%1$s мүчүлүштүктөрдү оңдоо маалыматын жүктөп бергиси келет." diff --git a/res/values-lo/strings.xml b/res/values-lo/strings.xml index d8185aa2e..ed1d55201 100644 --- a/res/values-lo/strings.xml +++ b/res/values-lo/strings.xml @@ -39,6 +39,7 @@ "ອະນຸຍາດສະເພາະເມື່ອມີການໃຊ້ແອັບ" "ແອັບ" "ສິດອະນຸຍາດແອັບ" + "ຕົວຈັດການສິດອະນຸຍາດ" "ບໍ່ຕ້ອງຖາມອີກ" "ບໍ່ມີສິດອະນຸຍາດ" "ການອະນຸຍາດເພີ່ມເຕີມ" @@ -51,7 +52,7 @@ "ເຮັດການດຳເນີນການທີ່ບໍ່ຮູ້ຈັກ" "ອະນຸຍາດແອັບ %1$d ຈາກທັງໝົດ %2$d ແອັບແລ້ວ" "ການນຳໃຊ້ຫຼ້າສຸດ" - "ເບິ່ງລາຍລະອຽດ" + "ເບິ່ງແຜງໜ້າປັດສິດອະນຸຍາດ" "ສະແດງລະບົບ" "ເຊື່ອງລະບົບ" "ບໍ່ມີແອັບ" @@ -90,9 +91,23 @@ "ສິດອະນຸຍາດປັດຈຸບັນ" "ກຳລັງຮຽງແອັບ…" "ບໍ່ຮູ້ຈັກ" - "ການນຳໃຊ້ສິດອະນຸຍາດ" - "ການເຂົ້າເຖິງຫຼ້າສຸດ: %1$s\n%2$s ການເຂົ້າເຖິງ" - "ການເຂົ້າເຖິງຫຼ້າສຸດ: %1$s\n%2$s ການເຂົ້າເຖິງ (%3$s ໃນພື້ນຫຼັງ)" + "ແຜງໜ້າປັດ" + + ການເຂົ້າເຖິງຫຼ້າສຸດ: %1$s\n%2$s ການເຂົ້າເຖິງ + ການເຂົ້າເຖິງຫຼ້າສຸດ: %1$s\n%2$s ການເຂົ້າເຖິງ + + + ການເຂົ້າເຖິງຫຼ້າສຸດ: %1$s\n%2$s ການເຂົ້າເຖິງ (%3$s ໃນພື້ນຫຼັງ) + ການເຂົ້າເຖິງຫຼ້າສຸດ: %1$s\n%2$s ການເຂົ້າເຖິງ (%3$s ໃນພື້ນຫຼັງ) + + + ການເຂົ້າເຖິງຫຼ້າສຸດ: %1$s\n%2$s ການເຂົ້າເຖິງ\nໄລຍະເວລາ: %3$s + ການເຂົ້າເຖິງຫຼ້າສຸດ: %1$s\n%2$s ການເຂົ້າເຖິງ\nໄລຍະເວລາ: %3$s + + + ການເຂົ້າເຖິງຫຼ້າສຸດ: %1$s\n%2$s ການເຂົ້າເຖິງ (%3$s ໃນພື້ນຫຼັງ)\nໄລຍະເວລາ: %3$s + ການເຂົ້າເຖິງຫຼ້າສຸດ: %1$s\n%2$s ການເຂົ້າເຖິງ (%3$s ໃນພື້ນຫຼັງ)\nໄລຍະເວລາ: %3$s + "ສິດອະນຸຍາດໃດກໍໄດ້" "ເວລາໃດກໍໄດ້" "7 ມື້ທີ່ຜ່ານມາ" @@ -135,6 +150,7 @@ "%1$s ບໍ່ໄດ້ເຂົ້າເຖິງ %2$s ຂອງທ່ານ." "ເບິ່ງການໃຊ້ສິດອະນຸຍາດແບບລະອຽດ" "ເຂົ້າເຖິງຫຼ້າສຸດ: %1$s" + "ບໍ່ເຄີຍເຂົ້າເຖິງ" "ອະນຸຍາດແລ້ວ" "ອະນຸຍາດສະເພາະໃນຕອນໃຊ້ຢູ່ເທົ່ານັ້ນ" "ຖືກປະຕິເສດ" diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml index 82ab2fe83..25faa83e1 100644 --- a/res/values-lt/strings.xml +++ b/res/values-lt/strings.xml @@ -39,6 +39,7 @@ "Leisti, tik kai programa naudojama" "Programos" "Programų leidimai" + "Leidimų tvarkytuvė" "Daugiau neklausti" "Nėra jokių leidimų" "Papildomi leidimai" @@ -53,7 +54,7 @@ "atlieka nežinomą veiksmą" "Leidžiama programų: %1$d%2$d" "Pastarasis naudojimas" - "Žr. išsamią informaciją" + "Žr. leidimų inform. suvestinę" "Rodyti sistemą" "Slėpti sistemą" "Nėra jokių programų" @@ -92,9 +93,31 @@ "Dabartiniai leidimai" "Programa pateikiama etapais…" "Nežinoma" - "Leidimų naudojimas" - "Paskutinį kartą pasiekta: %1$s\npasiekta tiek kartų: %2$s" - "Paskutinį kartą pasiekta: %1$s\npasiekta tiek kartų: %2$s (%3$s fone)" + "Informacijos suvestinė" + + Paskutinį kartą pasiekta: %1$s\nPasiekta %2$s kartą + Paskutinį kartą pasiekta: %1$s\nPasiekta %2$s kartus + Paskutinį kartą pasiekta: %1$s\nPasiekta %2$s karto + Paskutinį kartą pasiekta: %1$s\nPasiekta %2$s kartų + + + Paskutinį kartą pasiekta: %1$s\nPasiekta %2$s kartą (%3$s fone) + Paskutinį kartą pasiekta: %1$s\nPasiekta %2$s kartus (%3$s fone) + Paskutinį kartą pasiekta: %1$s\nPasiekta %2$s karto (%3$s fone) + Paskutinį kartą pasiekta: %1$s\nPasiekta %2$s kartų (%3$s fone) + + + Paskutinį kartą pasiekta: %1$s\nPasiekta %2$s kartą\nTrukmė: %3$s + Paskutinį kartą pasiekta: %1$s\nPasiekta %2$s kartus\nTrukmė: %3$s + Paskutinį kartą pasiekta: %1$s\nPasiekta %2$s karto\nTrukmė: %3$s + Paskutinį kartą pasiekta: %1$s\nPasiekta %2$s kartų\nTrukmė: %3$s + + + Paskutinį kartą pasiekta: %1$s\nPasiekta %2$s kartą (%3$s fone)\nTrukmė: %3$s + Paskutinį kartą pasiekta: %1$s\nPasiekta %2$s kartus (%3$s fone)\nTrukmė: %3$s + Paskutinį kartą pasiekta: %1$s\nPasiekta %2$s karto (%3$s fone)\nTrukmė: %3$s + Paskutinį kartą pasiekta: %1$s\nPasiekta %2$s kartų (%3$s fone)\nTrukmė: %3$s + "Bet koks leidimas" "Bet koks laikas" "Pastarosios 7 dienos" @@ -137,6 +160,7 @@ "Programa „%1$s“ neturėjo prieigos prie: %2$s." "Žiūrėti išsamią leidimų naudojimo informaciją" "Paskutinį kartą pasiekta: %1$s" + "Niekada nebuvo pasiekta" "Leidžiama" "Leidžiama, tik kol naudojama" "Atmesta" diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml index e70e4c16c..e7edc7117 100644 --- a/res/values-lv/strings.xml +++ b/res/values-lv/strings.xml @@ -39,6 +39,7 @@ "Atļaut tikai lietotnes izmantošanas laikā" "Lietotnes" "Lietotņu atļaujas" + "Atļauju pārvaldnieks" "Vairs nejautāt" "Nav atļauju" "Papildu atļaujas" @@ -52,7 +53,7 @@ "veikt nezināmu darbību" "Atļautas %1$d lietotnes no %2$d" "Nesens lietojums" - "Skatīt detalizētu informāciju" + "Skatīt atļauju inform. paneli" "Rādīt sistēmas lietotnes" "Slēpt sistēmas lietotnes" "Nav lietotņu" @@ -91,9 +92,27 @@ "Pašreizējās atļaujas" "Lietotne tiek izstādīta…" "Nezināma" - "Atļauju lietojums" - "Pēdējā piekļuve: %1$s\n%2$s piekļuves gadījums(-i)" - "Pēdējā piekļuve: %1$s\n%2$s piekļuves gadījums(-i) (%3$s fonā)" + "Informācijas panelis" + + Pēdējā piekļuve: %1$s\n%2$s piekļuves gadījumi + Pēdējā piekļuve: %1$s\n%2$s piekļuves gadījums + Pēdējā piekļuve: %1$s\n%2$s piekļuves gadījumi + + + Pēdējā piekļuve: %1$s\n%2$s piekļuves gadījumi (%3$s fonā) + Pēdējā piekļuve: %1$s\n%2$s piekļuves gadījums (%3$s fonā) + Pēdējā piekļuve: %1$s\n%2$s piekļuves gadījumi (%3$s fonā) + + + Pēdējā piekļuve: %1$s\n%2$s piekļuves gadījumi\nIlgums: %3$s + Pēdējā piekļuve: %1$s\n%2$s piekļuves gadījums\nIlgums: %3$s + Pēdējā piekļuve: %1$s\n%2$s piekļuves gadījumi\nIlgums: %3$s + + + Pēdējā piekļuve: %1$s\n%2$s piekļuves gadījumi (%3$s fonā)\nIlgums: %3$s + Pēdējā piekļuve: %1$s\n%2$s piekļuves gadījums (%3$s fonā)\nIlgums: %3$s + Pēdējā piekļuve: %1$s\n%2$s piekļuves gadījumi (%3$s fonā)\nIlgums: %3$s + "Jebkura atļauja" "Jebkurā laikā" "Pēdējās 7 dienās" @@ -136,6 +155,7 @@ "Lietotnei %1$s nav piekļuves %2$s." "Skatīt detalizētu informāciju par atļauju lietojumu" "Pēdējā piekļuve: %1$s" + "Nekad nav piekļūts" "Atļauts" "Atļauts tikai izmantošanas laikā" "Noraidīts" diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml index 7a894bd4d..440d9d9f7 100644 --- a/res/values-mk/strings.xml +++ b/res/values-mk/strings.xml @@ -39,6 +39,7 @@ "Дозволи само додека се користи апликацијата" "Апликации" "Дозволи за апликацијата" + "Управник со дозволи" "Не прашувај повторно" "Нема дозволи" "Дополнителни дозволи" @@ -51,7 +52,7 @@ "изврши непознато дејство" "Дозволени се %1$d од %2$d апликации" "Неодамнешно користење" - "Прикажи ги деталите" + "Контролна табла со дозволи" "Прикажи го системот" "Сокриј го системот" "Нема апликации" @@ -90,9 +91,23 @@ "Тековни дозволи" "Апликацијата се поставува…" "Непознатo" - "Користење дозволи" - "Последен пристап: %1$s\n%2$s пристапи" - "Последен пристап: %1$s\n%2$s пристапи (%3$s во заднина)" + "Контролна табла" + + Последен пристап: %1$s\n%2$s пристап + Последен пристап: %1$s\n%2$s пристапи + + + Последен пристап: %1$s\n%2$s пристап (%3$s во заднина) + Последен пристап: %1$s\n%2$s пристапи (%3$s во заднина) + + + Последен пристап: %1$s\n%2$s пристап\nВреметраење: %3$s + Последен пристап: %1$s\n%2$s пристапи\nВреметраење: %3$s + + + Последен пристап: %1$s\n%2$s пристап (%3$s во заднина)\nВреметраење: %3$s + Последен пристап: %1$s\n%2$s пристапи (%3$s во заднина)\nВреметраење: %3$s + "Која било дозвола" "Кога било" "Последните 7 дена" @@ -135,6 +150,7 @@ "%1$s не пристапила до вашата %2$s." "Прегледајте го деталното користење на дозволите" "Последен пристап: %1$s" + "Никогаш не е пристапено" "Дозволени" "Дозволени само кога се користат" "Одбиени" diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml index efd9a7219..bd09ba1f3 100644 --- a/res/values-ml/strings.xml +++ b/res/values-ml/strings.xml @@ -39,6 +39,7 @@ "ആപ്പ് ഉപയോഗത്തിലുള്ളപ്പോൾ മാത്രം അനുവദിക്കുക" "ആപ്പുകൾ" "ആപ്പ് അനുമതികൾ" + "അനുമതി മാനേജർ" "വീണ്ടും ആവശ്യപ്പെടരുത്" "അനുമതികൾ ഇല്ല" "അധിക അനുമതികൾ" @@ -51,7 +52,7 @@ "ഒരു അജ്ഞാത പ്രവർത്തനം നടത്തുക" "%1$d / %2$d ആപ്പുകൾ അനുവദനീയം" "അടുത്തിടെയുള്ള ഉപയോഗം" - "വിശദാംശങ്ങൾ കാണുക" + "അനുമതി ഡാഷ്‌ബോർഡ് കാണുക" "സിസ്‌റ്റം ദൃശ്യമാക്കുക" "സിസ്‌റ്റം അദൃശ്യമാക്കുക" "ആപ്പുകൾ ഒന്നുമില്ല" @@ -90,9 +91,23 @@ "നിലവിലെ അനുമതികൾ" "ആപ്പ് തയ്യാറാക്കുന്നു…" "അജ്ഞാതം" - "അനുമതികളുടെ ഉപയോഗം" - "അവസാന ആക്‌സസ്: %1$s\n%2$s ആക്‌സസുകള്‍" - "അവസാന ആക്‌സസ്: %1$s\n%2$s ആക്‌സസുകള്‍ (പശ്‌ചാത്തലത്തില്‍ %3$s എണ്ണം)" + "ഡാഷ്‌ബോർഡ്" + + അവസാനം ആക്‌‌സസ് ചെയ്‌തത്: %1$s\n%2$s ആക്‌സസുകള്‍ + അവസാനം ആക്‌‌സസ് ചെയ്‌തത്: %1$s\n%2$s ആക്‌‌സസ് + + + അവസാനം ആക്‌‌സസ് ചെയ്‌തത്: %1$s\n%2$s ആക്‌സസുകള്‍ (പശ്‌ചാത്തലത്തില്‍ %3$s എണ്ണം) + അവസാനം ആക്‌‌സസ് ചെയ്‌തത്: %1$s\n%2$s ആക്‌‌സസ് (പശ്‌ചാത്തലത്തില്‍%3$s എണ്ണം) + + + അവസാനം ആക്‌‌സസ് ചെയ്‌തത്: %1$s\n%2$s ആക്‌സസുകള്\nസമയ ദൈർഘ്യം: %3$s + അവസാനം ആക്‌‌സസ് ചെയ്‌തത്: %1$s\n%2$s ആക്‌‌സസ്\nസമയ ദൈർഘ്യം: %3$s + + + അവസാനം ആക്‌‌സസ് ചെയ്‌തത്: %1$s\n%2$s ആക്‌സസുകള്‍ (പശ്ചാത്തലത്തിൽ %3$s എണ്ണം)\nസമയ ദൈർഘ്യം: %3$s + അവസാനം ആക്‌‌സസ് ചെയ്‌തത്: %1$s\n%2$s ആക്‌സസ് (പശ്ചാത്തലത്തിൽ %3$s എണ്ണം)\nസമയ ദൈർഘ്യം: %3$s + "ഏതെങ്കിലും അനുമതി" "ഏത് സമയത്തും" "കഴിഞ്ഞ 7 ദിവസം" @@ -135,6 +150,7 @@ "%1$s നിങ്ങളുടെ %2$sആക്‌‌സസ് ചെയ്‌തിട്ടില്ല." "അനുമതികളുടെ വിശദമായ ഉപയോഗം കാണുക" "അവസാനം ആക്‌‌സസ് ചെയ്‌തത്: %1$s" + "ഒരിക്കലും ആക്‌‌സസ് ചെയ്‌തിട്ടില്ല" "അനുവദിച്ചവ" "ഉപയോഗിക്കുമ്പോൾ മാത്രം അനുവദനീയം" "നിരസിച്ചവ" @@ -168,16 +184,11 @@ "തുറക്കുക" "അൺഇൻസ്‌റ്റാൾ ചെയ്യുക" "നിർബന്ധിതമായി നിർത്തുക" - - - - - - - - - - + "ക്രമീകരണം" + "നിങ്ങളുടെ ഉപകരണത്തിലേക്ക് %s എന്നതിന് പൂർണ്ണമായ ആക്‌സസുണ്ട്" + "നിങ്ങളുടെ ഉപകരണത്തിലേക്ക് %s ഉപയോഗസഹായി സേവനങ്ങൾക്ക് പൂർണ്ണമായ ആക്‌സസുണ്ട്" + "%s എന്നതിന് നിങ്ങളുടെ സ്‌ക്രീൻ, പ്രവർത്തനങ്ങൾ, ഇൻപുട്ടുകൾ എന്നിവ കാണാനും പ്രവർത്തനങ്ങൾ നിർവഹിക്കാനും, ഡിസ്‌പ്ലേ നിയന്ത്രിക്കാനും കഴിയും." + "ഈ സേവനങ്ങൾക്ക് നിങ്ങളുടെ സ്‌ക്രീൻ, പ്രവർത്തനങ്ങൾ, ഇൻപുട്ടുകൾ എന്നിവ കാണാനും പ്രവർത്തനങ്ങൾ നിർവഹിക്കാനും, ഡിസ്‌പ്ലേ നിയന്ത്രിക്കാനും കഴിയും." "ഡിഫോൾട്ട് ആപ്പുകൾ" "ഡിഫോൾട്ട് ആപ്പുകൾ ഇല്ല" "ജോലി ആവശ്യങ്ങൾക്ക് ഡിഫോൾട്ട്" @@ -199,11 +210,9 @@ "കോൾ സ്‌ക്രീനിംഗ് ആപ്പ്" "കോൾ സഹകാരി ആപ്പ്" "കാർ പ്രൊജക്ഷൻ ആപ്പ്" - - + "ഔദ്യോഗിക പ്രൊഫൈലിനെ പിന്തുണയ്‌ക്കുന്നില്ല" "ശ്രദ്ധിക്കുക: നിങ്ങളുടെ ഉപകരണം റീസ്‌റ്റാർട്ട് ചെയ്‌ത്, സ്‌ക്രീൻ ലോക്ക് സജ്ജീകരിച്ചിട്ടുണ്ടെങ്കിൽ, നിങ്ങളുടെ ഉപകരണം അൺലോക്ക് ചെയ്യുന്നത് വരെ ഈ ആപ്പ് ആരംഭിക്കാനാവില്ല." - - + "നിങ്ങളുടെ സ്ക്രീനിൽ ദൃശ്യമാകുന്നതോ ആപ്പുകൾക്കുള്ളിൽ ആക്‌സസ് ചെയ്യാവുന്നതോ ആയ വിവരങ്ങൾ ഉൾപ്പെടെ, നിങ്ങളുടെ സിസ്‌റ്റത്തിൽ ഉപയോഗത്തിലുള്ള ആപ്പുകളെ കുറിച്ചുള്ള വിവരങ്ങൾ വായിക്കാൻ അസിസ്‌റ്റൻ്റിനാവും." "ഡീബഗ്ഗ് ചെയ്യൽ ഡാറ്റ പങ്കിടുക" "വിശദമായ ഡീബഗ്ഗ് ചെയ്യൽ വിവരങ്ങൾ പങ്കിടണോ?" "ഡീബഗ്ഗ് ചെയ്യൽ വിവരങ്ങൾ അപ്‌ലോഡ് ചെയ്യാൻ %1$s താൽപ്പര്യപ്പെടുന്നു." diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml index 73e2aab76..5091e5fdc 100644 --- a/res/values-mn/strings.xml +++ b/res/values-mn/strings.xml @@ -39,6 +39,7 @@ "Зөвхөн аппыг ашиглаж байх үед зөвшөөрөх" "Аппууд" "Аппын зөвшөөрөл" + "Зөвшөөрлийн менежер" "Дахин бүү асуу" "Зөвшөөрөл алга" "Нэмэлт зөвшөөрөл" @@ -51,7 +52,7 @@ "тодорхойгүй үйлдэл хийх" "%2$d%1$d аппыг зөвшөөрсөн" "Саяхны ашиглалт" - "Дэлгэрэнгүй мэдээллийг харах" + "Зөвшөөрлийн хяналтын самбарыг харах" "Системийг харуулах" "Системийг нуух" "Апп алга" @@ -90,9 +91,23 @@ "Одоогийн зөвшөөрөл" "Аппыг байршуулж байна…" "Тодорхойгүй" - "Зөвшөөрлийн хэрэглээ" - "Сүүлийн хандалт: %1$s\n%2$s хандалт" - "Сүүлийн хандалт: %1$s\n%2$s хандалт (ард %3$s)" + "Хяналтын самбар" + + Сүүлийн хандалт: %1$s\n%2$s хандалт + Сүүлийн хандалт: %1$s\n%2$s хандалт + + + Сүүлийн хандалт: %1$s\n%2$s хандалт (ард %3$s) + Сүүлийн хандалт: %1$s\n%2$s хандалт (ард %3$s) + + + Сүүлийн хандалт: %1$s\n%2$s хандалт\nХугацаа: %3$s + Сүүлийн хандалт: %1$s\n%2$s хандалт\nХугацаа: %3$s + + + Сүүлийн хандалт: %1$s\n%2$s хандалт (ард %3$s)\nХугацаа: %3$s + Сүүлийн хандалт: %1$s\n%2$s хандалт (ард %3$s)\nХугацаа: %3$s + "Дурын зөвшөөрөл" "Дурын хугацаа" "Сүүлийн 7 хоног" @@ -135,6 +150,7 @@ "%1$s таны %2$s-д хандаагүй байна." "Зөвшөөрлийн дэлгэрэнгүй ашиглалтыг харах" "Хамгийн сүүлийн хандалт: %1$s" + "Хэзээ ч хандаагүй" "Зөвшөөрсөн" "Зөвхөн ашиглалтад байхад зөвшөөрөгдсөн" "Татгалзсан" diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml index 4f9422a16..76ebe09aa 100644 --- a/res/values-mr/strings.xml +++ b/res/values-mr/strings.xml @@ -39,6 +39,7 @@ "फक्त अ‍ॅप वापरत असताना अनुमती द्या" "अॅप्स" "अ‍ॅप परवानग्या" + "परवानगी व्यवस्थापक" "पुन्हा विचारू नका" "परवानग्या नाहीत" "अतिरिक्त परवानग्या" @@ -51,7 +52,7 @@ "अज्ञात क्रिया करा" "%1$d पैकी %2$d अ‍ॅप्सना परवानगी दिली" "अलीकडील वापर" - "तपशील पाहा" + "परवानग्या डॅशबोर्ड पाहा" "सिस्टम दर्शवा" "सिस्टम लपवा" "कोणतेही अॅप्स नाहीत" @@ -90,9 +91,23 @@ "वर्तमान परवानग्या" "अ‍ॅप सुरुवातीच्या स्थितीत आहे…" "अज्ञात" - "परवानगी वापर" - "शेवटचा अ‍ॅक्सेस: %1$s\n%2$s अ‍ॅक्सेस" - "शेवटचा अ‍ॅक्सेस: %1$s\n%2$s अ‍ॅक्सेस (बॅकग्राउंडमध्ये %3$s)" + "डॅशबोर्ड" + + शेवटचा अ‍ॅक्सेस: %1$s\n%2$s अ‍ॅक्सेस + शेवटचा अ‍ॅक्सेस: %1$s\n%2$s अ‍ॅक्सेस + + + शेवटचा अ‍ॅक्सेस: %1$s\n%2$s अ‍ॅक्सेस (बॅकग्राउंडमध्ये %3$s) + शेवटचा अ‍ॅक्सेस: %1$s\n%2$s अ‍ॅक्सेस (बॅकग्राउंडमध्ये %3$s) + + + शेवटचा अ‍ॅक्सेस: %1$s\n%2$s अ‍ॅक्सेस\nकालावधी: %3$s + शेवटचा अ‍ॅक्सेस: %1$s\n%2$s अ‍ॅक्सेस\nकालावधी: %3$s + + + शेवटचा अ‍ॅक्सेस: %1$s\n%2$s अ‍ॅक्सेस (बॅकग्राउंडमध्ये %3$s)\n कालावधी: %3$s + शेवटचा अ‍ॅक्सेस: %1$s\n%2$s अ‍ॅक्सेस (बॅकग्राउंडमध्ये %3$s)\n कालावधी: %3$s + "कोणतीही परवानगी" "कधीही" "शेवटचे सात दिवस" @@ -135,6 +150,7 @@ "%1$s ला तुमच्या %2$sचा अॅक्सेस दिलेला नाही." "परवानग्यांचा वापर तपशीलवार पाहा" "शेवटचा अ‍ॅक्सेस: %1$s" + "कधीही अ‍ॅक्सेस केलेले नाही" "अनुमती असलेले" "फक्त वापरत असताना अनुमती आहे" "नाकारलेली" @@ -168,16 +184,11 @@ "उघडा" "अनइंस्टॉल करा" "सक्तीने थांबवा" - - - - - - - - - - + "सेटिंग्ज" + "%s ला तुमच्या डिव्हाइसचा पुर्ण अ‍ॅक्सेस आहे" + "%s अ‍ॅक्सेसिबिलिटी सेवांना तुमच्या डिव्हाइसचा पुर्ण अ‍ॅक्सेस आहे" + "%s तुमची स्क्रीन, क्रिया आणि इनपुट, करत असलेल्या क्रिया पाहू शकेल आणि डिस्प्ले नियंत्रित करू शकेल." + "या सेवा तुमची स्क्रीन, क्रिया आणि इनपुट पाहू शकतात, क्रिया करू शकतात आणि डिस्प्ले नियंत्रित करू शकतात." "डीफॉल्ट अ‍ॅप्स" "कोणतीही डीफॉल्‍ट अ‍ॅप्स नाहीत" "कार्यासाठी डीफॉल्ट" @@ -199,11 +210,9 @@ "स्क्रीनिंग अ‍ॅपला कॉल करा" "सहयोगी अ‍ॅपला कॉल करा" "कार प्रोजेक्शन अ‍ॅप" - - + "कार्य प्रोफाइलला सपोर्ट नाही" "टीप: तुम्ही तुमचे डिव्हाइस रीस्टार्ट केल्यास आणि स्क्रीन लॉक सेट केले असल्यास, तुम्ही तुमचे डिव्हाइस अनलॉक करेपर्यंत हे अ‍ॅप सुरू होऊ शकत नाही." - - + "तुमच्या स्क्रीनवर दृश्‍यमान असलेल्या माहितीच्या किंवा अ‍ॅप्समध्ये अ‍ॅक्सेस करता येणाऱ्या माहितीच्या समावेशासह असिस्टंट तुमच्या सिस्टिममध्ये वापरल्या जाणाऱ्या अ‍ॅप्सबद्दलची माहिती वाचू शकेल." "डीबगिंग डेटा शेअर करा" "तपशीलवार डीबगिंग डेटा शेअर करायचा?" "%1$s ला डीबगिंग माहिती अपलोड करायला आवडेल." diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml index 78562f843..0c16cf9e0 100644 --- a/res/values-ms/strings.xml +++ b/res/values-ms/strings.xml @@ -39,6 +39,7 @@ "Benarkan hanya semasa apl sedang digunakan" "Apl" "Kebenaran apl" + "Pengurus kebenaran" "Jangan tanya lagi" "Tiada kebenaran" "Kebenaran tambahan" @@ -51,7 +52,7 @@ "laksanakan tindakan yang tidak diketahui" "%1$d daripada %2$d apl dibenarkan" "Penggunaan terbaharu" - "Lihat butiran" + "Lihat Papan Pemuka Kebenaran" "Tunjukkan sistem" "Sembunyikan sistem" "Tiada apl" @@ -90,9 +91,23 @@ "Kebenaran semasa" "Pemeringkatan apl…" "Tidak diketahui" - "Penggunaan kebenaran" - "Akses terakhir: %1$s\n%2$s akses" - "Akses terakhir: %1$s\n%2$s akses (%3$s di latar belakang)" + "Papan Pemuka" + + Akses terakhir: %1$s\n%2$s akses + Akses terakhir: %1$s\n%2$s akses + + + Akses terakhir: %1$s\n%2$s akses (%3$s di latar belakang) + Akses terakhir: %1$s\n%2$s akses (%3$s di latar belakang) + + + Akses terakhir: %1$s\n%2$s akses\nTempoh: %3$s + Akses terakhir: %1$s\n%2$s akses\nTempoh: %3$s + + + Akses terakhir: %1$s\n%2$s akses (%3$s di latar belakang)\nTempoh: %3$s + Akses terakhir: %1$s\n%2$s akses (%3$s di latar belakang)\nTempoh: %3$s + "Sebarang kebenaran" "Pada bila-bila masa" "7 hari yang lalu" @@ -135,6 +150,7 @@ "%1$s belum mengakses %2$s anda." "Lihat penggunaan kebenaran terperinci" "Akses terakhir: %1$s" + "Tidak pernah mengakses" "Dibenarkan" "Dibenarkan hanya semasa dalam penggunaan" "Ditolak" diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml index ac5252494..11c74e572 100644 --- a/res/values-my/strings.xml +++ b/res/values-my/strings.xml @@ -39,6 +39,7 @@ "အက်ပ်အသုံးပြုချိန်တွင်သာ ခွင့်ပြုရန်" "အက်ပ်များ" "အက်ပ်ခွင့်ပြုချက်များ" + "ခွင့်ပြုချက် မန်နေဂျာ" "ထပ်မမေးပါနှင့်" "ခွင့်ပြုချက်မရှိပါ" "ထပ်ဆောင်း ခွင့်ပြုချက်များ" @@ -51,7 +52,7 @@ "အမျိုးအမည်မသိ ဆောင်ရွက်ချက်တစ်ခု လုပ်ရန်" "အက်ပ် %2$d ခုထဲမှ %1$d ခု ခွင့်ပြုသည်" "လတ်တလ​ော အသုံးပြုမှု" - "အသေးစိတ်ကြည့်ရန်" + "ခွင့်ပြုမှုဒက်ရှ်ဘုတ် ကြည့်ရန်" "စနစ်ကိုပြသရန်" "စနစ်ကို ဖျောက်ရန်" "အက်ပ် မရှိပါ" @@ -90,9 +91,23 @@ "လက်ရှိ ခွင့်ပြုချက်များ" "အက်ပ်ကို ပြင်ဆင်နေသည်…" "အမည်မသိ" - "ခွင့်ပြုချက်များ အသုံးပြုမှု" - "နောက်ဆုံးအသုံးပြုခဲ့ချိန်− %1$s\nအသုံးပြုကြိမ် %2$s ကြိမ်" - "နောက်ဆုံးအသုံးပြုခဲ့ချိန်− %1$s\nအသုံးပြုကြိမ် %2$s ကြိမ် (နောက်ခံတွင် %3$s ခု)" + "ဒက်ရှ်ဘုတ်" + + နောက်ဆုံးအသုံးပြုမှု- %1$s\nအသုံးပြုမှု %2$s ခု + နောက်ဆုံးအသုံးပြုမှု- %1$s\nအသုံးပြုမှု %2$s ခု + + + နောက်ဆုံးအသုံးပြုမှု- %1$s\nအသုံးပြုမှု %2$s ခု (နောက်ခံတွင် %3$s ခု) + နောက်ဆုံးအသုံးပြုမှု- %1$s\nအသုံးပြုမှု %2$s ခု (နောက်ခံတွင် %3$s ခု) + + + နောက်ဆုံးအသုံးပြုမှု- %1$s\nအသုံးပြုမှု %2$s ခု\nကြာချိန်- %3$s + နောက်ဆုံးအသုံးပြုမှု- %1$s\nအသုံးပြုမှု %2$s ခု\nကြာချိန်- %3$s + + + နောက်ဆုံးအသုံးပြုမှု- %1$s\nအသုံးပြုမှု %2$s ခု (နောက်ခံတွင် %3$s ခု)\nကြာချိန်- %3$s + နောက်ဆုံးအသုံးပြုမှု- %1$s\nအသုံးပြုမှု %2$s ခု (နောက်ခံတွင် %3$s ခု)\nကြာချိန်- %3$s + "မည်သည့် ခွင့်ပြုချက်မဆို" "အချိန်မရွေး" "ပြီးခဲ့သော ၇ ရက်" @@ -135,6 +150,7 @@ "%1$s က သင်၏ %2$s ကို ဝင်သုံးမထားပါ။" "ခွင့်ပြုချက်များ အသုံးပြုမှု အသေးစိတ်ကို ကြည့်ရန်" "နောက်ဆုံး အသုံးပြုချိန်- %1$s" + "တစ်ခါမျှ အသုံးပြုမထားပါ" "ခွင့်ပြုထားသည်" "အသုံးပြုစဉ်တွင်သာ ခွင့်ပြုထားသည်" "ငြင်းပယ်ထားသည်" diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml index 30ee97a22..1d2dfa990 100644 --- a/res/values-nb/strings.xml +++ b/res/values-nb/strings.xml @@ -39,6 +39,7 @@ "Bare tillat mens appen er i bruk" "Apper" "Apptillatelser" + "Tillatelsesadministrator" "Ikke spør igjen" "Ingen tillatelser" "Flere tillatelser" @@ -51,7 +52,7 @@ "utføre en ukjent handling" "%1$d av %2$d apper er tillatt" "Nylig bruk" - "Se detaljer" + "Se tillatelsesoversikten" "Vis systemapper" "Skjul systemapper" "Ingen apper" @@ -90,9 +91,23 @@ "Gjeldende tillatelser" "Klargjør appen …" "Ukjent" - "Bruk av tillatelser" - "Siste tilgang: %1$s\nbrukt %2$s ganger" - "Siste tilgang: %1$s\nbrukt %2$s ganger (%3$s i bakgrunnen)" + "Oversikt" + + Sist brukt: %1$s\n%2$s ganger + Sist brukt: %1$s\n%2$s gang + + + Sist brukt: %1$s\n%2$s ganger (%3$s i bakgrunnen) + Sist brukt: %1$s\n%2$s gang (%3$s i bakgrunnen) + + + Sist brukt: %1$s\n%2$s ganger\nVarighet: %3$s + Sist brukt: %1$s\n%2$s gang\nVarighet: %3$s + + + Sist brukt: %1$s\n%2$s ganger (%3$s i bakgrunnen)\nVarighet: %3$s + Sist brukt: %1$s\n%2$s gang (%3$s i bakgrunnen)\nVarighet: %3$s + "Hvilken som helst tillatelse" "Når som helst" "De siste 7 dagene" @@ -135,6 +150,7 @@ "%1$s har ikke brukt %2$s." "Vis detaljert bruk av tillatelser" "Siste tilgang: %1$s" + "Aldri brukt" "Tillatt" "Tillates bare når appen brukes" "Avvist" diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml index 7a42d8339..9123211c6 100644 --- a/res/values-ne/strings.xml +++ b/res/values-ne/strings.xml @@ -39,6 +39,7 @@ "अनुप्रयोग प्रयोगमा भएको बेलामा मात्र अनुमति दिनुहोस्‌" "अनुप्रयोगहरू" "अनुप्रयोगसम्बन्धी अनुमति" + "अनुमतिका प्रबन्धक" "फेरि नसोध्नुहोला" "अनुमति दिन भनी कुनै अनुरोध छैन" "अतिरिक्त अनुमति" @@ -51,7 +52,7 @@ "कुनै अज्ञात कारबाही गर्नुहोस्" "%2$d मध्ये %1$d अनुप्रयोगहरूलाई अनुमति दिइएको छ" "हालसालैको उपयोग" - "विवरणहरू हेर्नुहोस्" + "अनुमतिसम्बन्धी ड्यासबोर्ड हेर्नुहोस्" "प्रणाली देखाउनुहोस्" "प्रणाली लुकाउनुहोस्" "कुनै पनि अनुप्रयोग छैन" @@ -90,9 +91,23 @@ "एपले हाल प्रयोग गर्ने अनुमति" "अनुप्रयोग स्थापना गर्न तयारी गर्दै…" "अज्ञात" - "अनुमतिको उपयोग" - "पछिल्लो पटक यति चोटि पहुँच राखियो: %1$s\n%2$s पहुँचहरू" - "पछिल्लो पटक यति चोटि पहुँच राखियो: %1$s %2$s \n पहुँचहरू (%3$sपृष्ठभूमिमा)" + "ड्यासबोर्ड" + + पछिल्लो पटकको पहुँच: %1$s\n%2$s पहुँच + पछिल्लो पटकको पहुँच: %1$s\n%2$s पहुँच + + + पछिल्लो पटकको पहुँच: %1$s %2$s \n पहुँचहरू (%3$sपृष्ठभूमिमा) + पछिल्लो पटकको पहुँच: %1$s\n%2$s पहुँच (%3$s पृष्ठभूमिमा) + + + पछिल्लो पटकको पहुँच: %1$s\n%2$s पहुँच\nअवधि: %3$s + पछिल्लो पटकको पहुँच: %1$s\n%2$s पहुँच\nअवधि: %3$s + + + पछिल्लो पटकको पहुँच: %1$s\n%2$s पहुँचहरू (%3$s पृष्ठभूमिमा)\nअवधि: %3$s + पछिल्लो पटकको पहुँच: %1$s\n%2$s पहुँच (%3$s पृष्ठभूमिमा)\nअवधि: %3$s + "कुनै पनि अनुमति" "कुनै पनि समय" "पछिल्ला ७ दिन" @@ -135,6 +150,7 @@ "%1$sतपाईंको %2$sमाथि पहुँच राखेको छैन।" "अनुमतिको विस्तृत उपयोग हेर्नुहोस्" "पछिल्लो पटक पहुँच राखिएको समय: %1$s" + "कहिल्यै पहुँच गरिएन" "अनुमति दिइएको" "प्रयोगमा भएका बेला मात्र अनुमति दिइन्छ" "अस्वीकार गरिएको" diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml index 5e2031031..7d73d23a7 100644 --- a/res/values-nl/strings.xml +++ b/res/values-nl/strings.xml @@ -39,6 +39,7 @@ "Alleen toestaan terwijl de app wordt gebruikt" "Apps" "App-machtigingen" + "Machtigingsbeheer" "Niet meer vragen" "Geen machtigingen" "Aanvullende machtigingen" @@ -51,7 +52,7 @@ "een onbekende actie uitvoeren" "Verleend aan %1$d van %2$d apps" "Recent gebruik" - "Details weergeven" + "Machtigingsdashboard weergeven" "Systeem-apps weergeven" "Systeem-apps verbergen" "Geen apps" @@ -90,9 +91,23 @@ "Huidige machtigingen" "App uitvoeren…" "Onbekend" - "Gebruik van machtigingen" - "Laatste keer geopend: %1$s\n%2$s toegangsacties" - "Laatste keer geopend: %1$s\n%2$s toegangsacties (%3$s op de achtergrond)" + "Dashboard" + + Laatste keer geopend: %1$s\n%2$s toegangsacties + Laatste keer geopend: %1$s\n%2$s toegangsactie + + + Laatste keer geopend: %1$s\n%2$s toegangsacties (%3$s op de achtergrond) + Laatste keer geopend: %1$s\n%2$s toegangsacties (%3$s op de achtergrond) + + + Laatste keer geopend: %1$s\n%2$s toegangsacties\nDuur: %3$s + Laatste keer geopend: %1$s\n%2$s toegangsactie\nDuur: %3$s + + + Laatste keer geopend: %1$s\n%2$s toegangsacties (%3$s op de achtergrond)\nDuur: %3$s + Laatste keer geopend: %1$s\n%2$s toegangsactie (%3$s op de achtergrond)\nDuur: %3$s + "Elke machtiging" "Altijd" "Afgelopen 7 dagen" @@ -135,6 +150,7 @@ "%1$s heeft geen toegang verkregen tot je %2$s." "Gedetailleerd machtigingsgebruik weergeven" "Laatste keer geopend: %1$s" + "Nooit geopend" "Toegestaan" "Alleen toegestaan tijdens gebruik" "Geweigerd" diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml index 0a5cf7182..bd245ac9a 100644 --- a/res/values-or/strings.xml +++ b/res/values-or/strings.xml @@ -39,6 +39,8 @@ "ଆପ୍‍ ବ୍ୟବହାରରେ ରହିଥିବା ବେଳେ କେବଳ ଅନୁମତି ଦିଅନ୍ତୁ" "ଆପ୍ସ" "ଆପ୍‌ ଅନୁମତିଗୁଡ଼ିକ" + + "ପୁଣି ପଚାରନ୍ତୁ ନାହିଁ" "କୌଣସି ଅନୁମତିଗୁଡ଼ିକ ନାହିଁ" "ଅତିରିକ୍ତ ଅନୁମତିଗୁଡ଼ିକ" @@ -51,7 +53,8 @@ "ଏହା ଏକ ଅଜଣା କାର୍ଯ୍ୟ ସମ୍ପାଦନ କରିଥାଏ" "%2$dଆପ୍ସରୁ %1$dକୁ ଅନୁମତି ଦିଆଯାଇଛି" "ନିକଟରେ ହୋଇଥିବା ବ୍ୟବହାର" - "ବିବରଣୀ ଦେଖନ୍ତୁ" + + "ସିଷ୍ଟମ୍‌ ଦେଖାନ୍ତୁ" "ସିଷ୍ଟମ୍‌କୁ ଲୁଚାନ୍ତୁ" "କୌଣସି ଆପ୍‌ ନାହିଁ" @@ -90,9 +93,12 @@ "ବର୍ତ୍ତମାନର ଅନୁମତିଗୁଡ଼ିକ" "ଆପ୍‍ ପର୍ଯ୍ୟାୟଭୁକ୍ତ କରାଯାଉଛି…" "ଅଜଣା" - "ବ୍ୟବହାର ପାଇଁ ଅନୁମତି" - "ଶେଷ ଆକ୍ସେସ୍: %1$s\n%2$sଟି ଆକ୍ସେସ୍‍" - "ଶେଷ ଆକ୍ସେସ୍: %1$s\n%2$s ଆକ୍ସେସ୍‍ (ପୃଷ୍ଠଭୂମିରେ %3$s)" + + + + + + "ଯେକୌଣସି ଅନୁମତି" "ଯେକୌଣସି ସମୟରେ" "ଗତ 7 ଦିନ" @@ -135,6 +141,8 @@ "%1$s ଆପଣଙ୍କ %2$s ଆକ୍ସେସ୍‍ ନାହିଁ।" "ବିସ୍ତୃତ ଅନୁମତି ବ୍ୟବହାର ଦେଖନ୍ତୁ" "ଶେଷ ଥର ପାଇଁ ଆକ୍ସେସ୍ କରାଯାଇଛି: %1$s" + + "ଅନୁମୋଦିତ" "କେବଳ ବ୍ୟବହାର ପାଇଁ ଅନୁମତି ଦିଆଯାଇଛି" "ପ୍ରତ୍ୟାଖ୍ୟାନ କରାଗଲା" @@ -168,16 +176,11 @@ "ଖୋଲନ୍ତୁ" "ଅନ୍‍ଇନ୍‍ଷ୍ଟଲ୍‌ କରନ୍ତୁ" "ଜବରଦସ୍ତି ବନ୍ଦ କରନ୍ତୁ" - - - - - - - - - - + "ସେଟିଂସ୍" + "ଆପଣଙ୍କ ଡିଭାଇସ୍‌କୁ %sର ସମ୍ପୂର୍ଣ୍ଣ ଆକ୍ସେସ୍‌ ଅଛି" + "%sଟି ଆକ୍ସେସିବିଲିଟୀ ସେବାକୁ ଆପଣଙ୍କ ଡିଭାଇସ୍‌ରେ ସମ୍ପୂର୍ଣ୍ଣ ଆକ୍ସେସ୍‌ ଅଛି" + "%s ଆପଣଙ୍କର ସ୍କ୍ରିନ୍‌, କାର୍ଯ୍ୟ ଏବଂ ଇନ୍‌ପୁଟ୍‍ ଦେଖିପାରିବ ଏବଂ କାର୍ଯ୍ୟ ସମ୍ପାଦନ କରିପାରିବ ଏବଂ ଡିସ୍‌ପ୍ଲେ ନିୟନ୍ତ୍ରଣ କରିପାରିବ।" + "ଏହି ସେବାଗୁଡ଼ିକ ଆପଣଙ୍କର ସ୍କ୍ରିନ୍‌, ପଦକ୍ଷେପ ଏବଂ ଇନ୍‌ପୁଟ୍‍ ଦେଖିପାରିବ ଏବଂ କାର୍ଯ୍ୟ ସମ୍ପାଦନ କରିପାରିବ ଏବଂ ଡିସ୍‌ପ୍ଲେ ନିୟନ୍ତ୍ରଣ କରିପାରିବ।" "ଡିଫଲ୍ଟ ଆପ୍ସ" "କୌଣସି ଡିଫଲ୍ଟ ଆପ୍ସ ନାହିଁ" "କାର୍ଯ୍ୟ ପାଇଁ ଡିଫଲ୍ଟ ଅଛି" @@ -199,11 +202,9 @@ "କଲ୍ ସ୍କ୍ରିନିଂ ଆପ୍" "ସହଯୋଗୀ ଆପ୍‌କୁ କଲ୍ କରନ୍ତୁ" "କାର୍ ପ୍ରୋଜେକ୍ସନ୍ ଆପ୍" - - + "ୱର୍କ ପ୍ରୋଫାଇଲ୍‍କୁ ସମର୍ଥନ କରେନାହିଁ" "ଟିପ୍ପଣୀ: ଯଦି ଆପଣ ଆପଣଙ୍କ ଡିଭାଇସ୍ ରିଷ୍ଟାର୍ଟ କରିବେ ଏବଂ ଏକ ସ୍କ୍ରିନ୍ ଲକ୍ ସେଟ୍ ହେବ, ଆପଣଙ୍କ ଡିଭାଇସ୍ ଅନ୍‌ଲକ୍ ନହେବା ପର୍ଯ୍ୟନ୍ତ ଏହି ଆପ୍ ଆରମ୍ଭ ହୋଇପାରିବ ନାହିଁ।" - - + "ଏହି ସହାୟକ, ସ୍କ୍ରିନ୍‌ରେ ଦେଖାଦେଉଥିବା କିମ୍ୱା ଆପ୍‌ଗୁଡ଼ିକ ମଧ୍ୟରେ ଆକ୍ସେସ୍ ହୋଇପାରିବା ଭଳି ସୂଚନା ସମେତ ଆପଣଙ୍କ ସିଷ୍ଟମ୍‌ରେ ଥିବା ଆପ୍‌ଗୁଡ଼ିକ ବିଷୟରେ ସୂଚନା ପଢ଼ିପାରିବ।" "ଡିବଗିଂ ଡାଟା ସେୟାର୍ କରନ୍ତୁ" "ବିସ୍ତୃତ ଡିବଗିଂ ଡାଟା ସେୟାର୍ କରିବେ?" "%1$s ଡିବଗିଂ ସୂଚନା ଅପ୍‌ଲୋଡ୍ କରିବାକୁ ଚାହାନ୍ତି।" diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml index e69084fa5..5cc02d869 100644 --- a/res/values-pa/strings.xml +++ b/res/values-pa/strings.xml @@ -39,6 +39,7 @@ "ਸਿਰਫ਼ ਐਪ ਵਰਤੇ ਜਾਣ ਵੇਲੇ ਕਰਨ ਦਿਓ" "ਐਪਾਂ" "ਐਪ ਇਜਾਜ਼ਤਾਂ" + "ਇਜਾਜ਼ਤ ਪ੍ਰਬੰਧਕ" "ਦੁਬਾਰਾ ਨਾ ਪੁੱਛੋ" "ਕੋਈ ਇਜਾਜ਼ਤਾਂ ਨਹੀਂ" "ਵਧੀਕ ਇਜਾਜ਼ਤਾਂ" @@ -51,7 +52,7 @@ "ਕੋਈ ਅਗਿਆਤ ਕਾਰਵਾਈ ਕਰੋ" "%2$d ਵਿੱਚੋਂ %1$d ਐਪਾਂ ਨੂੰ ਆਗਿਆ ਦਿੱਤੀ" "ਹਾਲੀਆ ਵਰਤੋਂ" - "ਵੇਰਵੇ ਦੇਖੋ" + "ਇਜਾਜ਼ਤਾਂ ਡੈਸ਼ਬੋਰਡ ਦੇਖੋ" "ਸਿਸਟਮ ਦਿਖਾਓ" "ਸਿਸਟਮ ਲੁਕਾਓ" "ਕੋਈ ਐਪਾਂ ਨਹੀਂ" @@ -90,9 +91,23 @@ "ਵਰਤਮਾਨ ਇਜਾਜ਼ਤਾਂ" "ਐਪ ਨੂੰ ਸਟੇਜ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…" "ਅਗਿਆਤ" - "ਇਜਾਜ਼ਤਾਂ ਵਰਤੋ" - "ਪਿਛਲੀ ਵਾਰ ਪਹੁੰਚ: %1$s\n%2$s ਪਹੁੰਚ" - "ਪਿਛਲੀ ਵਾਰ ਪਹੁੰਚ: %1$s\n%2$s ਪਹੁੰਚ (ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ %3$s)" + "ਡੈਸ਼ਬੋਰਡ" + + ਪਿਛਲੀ ਵਾਰ ਪਹੁੰਚ: %1$s\n%2$s ਪਹੁੰਚ + ਪਿਛਲੀ ਵਾਰ ਪਹੁੰਚ: %1$s\n%2$s ਪਹੁੰਚਾਂ + + + ਪਿਛਲੀ ਵਾਰ ਪਹੁੰਚ: %1$s\n%2$s ਪਹੁੰਚ (ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ %3$s) + ਪਿਛਲੀ ਵਾਰ ਪਹੁੰਚ: %1$s\n%2$s ਪਹੁੰਚਾਂ (ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ %3$s) + + + ਪਿਛਲੀ ਵਾਰ ਪਹੁੰਚ: %1$s\n%2$s ਪਹੁੰਚ\nਮਿਆਦ: %3$s + ਪਿਛਲੀ ਵਾਰ ਪਹੁੰਚ: %1$s\n%2$s ਪਹੁੰਚਾਂ\nਮਿਆਦ: %3$s + + + ਪਿਛਲੀ ਵਾਰ ਪਹੁੰਚ: %1$s\n%2$s ਪਹੁੰਚ (ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ %3$s)\nਮਿਆਦ: %3$s + ਪਿਛਲੀ ਵਾਰ ਪਹੁੰਚ: %1$s\n%2$s ਪਹੁੰਚਾਂ (ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ %3$s)\nਮਿਆਦ: %3$s + "ਕੋਈ ਵੀ ਇਜਾਜ਼ਤ" "ਕਿਸੇ ਵੀ ਵੇਲੇ" "ਪਿਛਲੇ 7 ਦਿਨ" @@ -135,6 +150,7 @@ "%1$s ਨੇ ਤੁਹਾਡੇ %2$s ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ।" "ਇਜਾਜ਼ਤਾਂ ਦੀ ਵਰਤੋਂ ਵੇਰਵੇ-ਸਹਿਤ ਦੇਖੋ" "ਪਿਛਲੀ ਵਾਰ ਪਹੁੰਚ: %1$s" + "ਕਦੇ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ" "ਮਨਜ਼ੂਰਸ਼ੁਦਾ" "ਸਿਰਫ਼ ਵਰਤੋਂ \'ਚ ਹੋਣ \'ਤੇ ਕਰਨ ਦਿੱਤਾ ਜਾਂਦਾ" "ਗੈਰ-ਮਨਜ਼ੂਰਸ਼ੁਦਾ" @@ -168,16 +184,11 @@ "ਖੋਲ੍ਹੋ" "ਅਣਸਥਾਪਤ ਕਰੋ" "ਜ਼ਬਰਦਸਤੀ ਬੰਦ ਕਰੋ" - - - - - - - - - - + "ਸੈਟਿੰਗਾਂ" + "%s ਕੋਲ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਤੱਕ ਪੂਰੀ ਪਹੁੰਚ ਹੈ" + "%s ਪਹੁੰਚਯੋਗਤਾ ਸੇਵਾਵਾਂ ਕੋਲ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਤੱਕ ਪੂਰੀ ਪਹੁੰਚ ਹੈ" + "%s ਐਪ ਤੁਹਾਡੀ ਸਕ੍ਰੀਨ, ਕਾਰਵਾਈਆਂ ਅਤੇ ਇਨਪੁੱਟਾਂ ਨੂੰ ਦੇਖ ਸਕਦੀ ਹੈ, ਕਾਰਵਾਈਆਂ ਕਰ ਸਕਦੀ ਹੈ ਅਤੇ ਡਿਸਪਲੇ ਕੰਟਰੋਲ ਕਰ ਸਕਦੀ ਹੈ।" + "ਇਹ ਸੇਵਾਵਾਂ ਤੁਹਾਡੀ ਸਕ੍ਰੀਨ, ਕਾਰਵਾਈਆਂ ਅਤੇ ਇਨਪੁੱਟਾਂ ਨੂੰ ਦੇਖ ਸਕਦੀ ਹੈ, ਕਾਰਵਾਈਆਂ ਕਰ ਸਕਦੀ ਹੈ ਅਤੇ ਡਿਸਪਲੇ ਕੰਟਰੋਲ ਕਰ ਸਕਦੀਆਂ ਹਨ।" "ਪੂਰਵ-ਨਿਰਧਾਰਤ ਐਪਾਂ" "ਕੋਈ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਐਪਾਂ ਨਹੀਂ" "ਕੰਮ ਲਈ ਪੂਰਵ-ਨਿਰਧਾਰਤ" @@ -199,11 +210,9 @@ "ਕਾਲ ਸਕ੍ਰੀਨਿੰਗ ਐਪ" "ਕਾਲ ਸੰਬੰਧੀ ਐਪ" "ਕਾਰ ਦੀ ਯੋਜਨਾਬੰਦੀ ਐਪ" - - + "ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਦੀ ਸੁਵਿਧਾ ਨਹੀਂ ਹੈ" "ਨੋਟ-ਕਥਨ: ਜੇਕਰ ਤੁਸੀਂ ਆਪਣੇ ਡੀਵਾਈਸ ਨੂੰ ਮੁੜ-ਸ਼ੁਰੂ ਕਰਦੇ ਹੋ ਅਤੇ ਸਕ੍ਰੀਨ ਲਾਕ ਸੈੱਟ ਕੀਤਾ ਹੋਇਆ ਹੈ, ਤਾਂ ਇਹ ਐਪਾ ਤੁਹਾਡੇ ਵੱਲੋਂ ਆਪਣੇ ਡੀਵਾਈਸ ਨੂੰ ਅਣਲਾਕ ਕੀਤੇ ਨਾ ਹੋਣ ਤੱਕ ਸ਼ੁਰੂ ਨਹੀਂ ਹੋਵੇਗੀ।" - - + "\'ਅਸਿਸਟੈਂਟ\' ਤੁਹਾਡੀ ਸਕ੍ਰੀਨ \'ਤੇ ਦਿਸਣਯੋਗ ਜਾਂ ਐਪਾਂ ਵਿੱਚ ਪਹੁੰਚਯੋਗ ਜਾਣਕਾਰੀ ਸਮੇਤ ਤੁਹਾਡੇ ਸਿਸਟਮ \'ਤੇ ਵਰਤੋਂ ਵਿੱਚ ਐਪਾਂ ਬਾਰੇ ਜਾਣਕਾਰੀ ਪੜ੍ਹ ਸਕੇਗੀ।" "ਡੀਬੱਗਿੰਗ ਡਾਟਾ ਸਾਂਝਾ ਕਰੋ" "ਕੀ ਵੇਰਵੇ ਸਮੇਤ ਡੀਬੱਗਿੰਗ ਡਾਟਾ ਸਾਂਝਾ ਕਰਨਾ ਹੈ?" "%1$s ਡੀਬੱਗਿੰਗ ਜਾਣਕਾਰੀ ਨੂੰ ਅੱਪਲੋਡ ਕਰਨਾ ਚਾਹੁੰਦੀ ਹੈ।" diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml index f80e7a741..ebde871c9 100644 --- a/res/values-pl/strings.xml +++ b/res/values-pl/strings.xml @@ -39,6 +39,7 @@ "Zezwalaj tylko podczas używania aplikacji" "Aplikacje" "Uprawnienia aplikacji" + "Menedżer uprawnień" "Nie pytaj ponownie" "Brak uprawnień" "Dodatkowe uprawnienia" @@ -53,7 +54,7 @@ "wykonywanie nieznanych działań" "Dostęp ma: %1$d%2$d aplikacji" "Ostatnie użycie" - "Wyświetl szczegóły" + "Wyświetl panel uprawnień" "Pokaż systemowe" "Ukryj systemowe" "Brak aplikacji" @@ -92,9 +93,31 @@ "Aktualne uprawnienia" "Przygotowuję aplikację…" "Inny" - "Użycie uprawnień" - "Ostatnie użycie: %1$s\nUżycia: %2$s" - "Ostatnie użycie: %1$s\nUżycia: %2$s (%3$s w tle)" + "Panel" + + Ostatnie użycie: %1$s\n%2$s użycia + Ostatnie użycie: %1$s\n%2$s użyć + Ostatnie użycie: %1$s\n%2$s użycia + Ostatnie użycie: %1$s\n%2$s użycie + + + Ostatnie użycie: %1$s\n%2$s użycia (%3$s w tle) + Ostatnie użycie: %1$s\n%2$s użyć (%3$s w tle) + Ostatnie użycie: %1$s\n%2$s użycia (%3$s w tle) + Ostatnie użycie: %1$s\n%2$s użycie (%3$s w tle) + + + Ostatnie użycie: %1$s\n%2$s użycia\nCzas trwania: %3$s + Ostatnie użycie: %1$s\n%2$s użyć\nCzas trwania: %3$s + Ostatnie użycie: %1$s\n%2$s użycia\nCzas trwania: %3$s + Ostatnie użycie: %1$s\n%2$s użycie\nCzas trwania: %3$s + + + Ostatnie użycie: %1$s\n%2$s użycia (%3$s w tle)\nCzas trwania: %3$s + Ostatnie użycie: %1$s\n%2$s użyć (%3$s w tle)\nCzas trwania: %3$s + Ostatnie użycie: %1$s\n%2$s użycia (%3$s w tle)\nCzas trwania: %3$s + Ostatnie użycie: %1$s\n%2$s użycie (%3$s w tle)\nCzas trwania: %3$s + "Dowolne uprawnienie" "Dowolny czas" "Ostatnie 7 dni" @@ -137,6 +160,7 @@ "Aplikacja %1$s nie korzysta z: %2$s." "Wyświetl szczegółowe użycie uprawnień" "Ostatnie użycie: %1$s" + "Nigdy nie użyto" "Dozwolone" "Zgoda na dostęp tylko podczas używania" "Niedozwolone" diff --git a/res/values-pt-rBR/strings.xml b/res/values-pt-rBR/strings.xml index e97b6a9e3..4e01252d0 100644 --- a/res/values-pt-rBR/strings.xml +++ b/res/values-pt-rBR/strings.xml @@ -39,6 +39,7 @@ "Permitir apenas enquanto o app estiver em uso" "Apps" "Permissões do app" + "Gerenciador de permissões" "Não perguntar novamente" "Sem permissões" "Outras permissões" @@ -51,7 +52,7 @@ "executar uma ação desconhecida" "%1$d de %2$d apps permitidos" "Uso recente" - "Ver detalhes" + "Ver o painel de permissões" "Mostrar sistema" "Ocultar sistema" "Nenhum app" @@ -90,9 +91,23 @@ "Permissões atuais" "Promovendo app…" "Desconhecido" - "Uso de permissões" - "Último acesso: %1$s\n%2$s acessos" - "Último acesso: %1$s\n%2$s acessos (%3$s em segundo plano)" + "Painel" + + Último acesso: %1$s\n%2$s + Últimos acessos: %1$s\n%2$s + + + Último acesso: %1$s\n%2$s (%3$s em segundo plano) + Últimos acessos: %1$s\n%2$s (%3$s em segundo plano) + + + Último acesso: %1$s\n%2$s\nDuração: %3$s + Últimos acessos: %1$s\n%2$s\nDuração: %3$s + + + Último acesso: %1$s\n%2$s (%3$s em segundo plano)\nDuração: %3$s + Últimos acessos: %1$s\n%2$s (%3$s em segundo plano)\nDuração: %3$s + "Qualquer permissão" "Qualquer horário" "Últimos 7 dias" @@ -135,6 +150,7 @@ "O app %1$s não acessou seu %2$s." "Ver uso detalhado das permissões" "Último acesso: %1$s" + "Nunca acessou" "Permitido" "Permitido apenas quando em uso" "Negado" diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml index 99406495d..fbc2fe03c 100644 --- a/res/values-pt-rPT/strings.xml +++ b/res/values-pt-rPT/strings.xml @@ -39,6 +39,7 @@ "Permitir apenas enquanto a aplicação está a ser utilizada" "Aplicações" "Autorizações da aplicação" + "Gestor de autorizações" "Não perguntar" "Sem autorizações" "Autorizações adicionais" @@ -51,7 +52,7 @@ "executar uma ação desconhecida" "%1$d de %2$d aplicações autorizadas" "Utilização recente" - "Ver detalhes" + "Ver Painel de autorizações" "Mostrar sistema" "Ocultar sistema" "Sem aplicações" @@ -90,9 +91,23 @@ "Autorizações atuais" "A preparar a aplicação…" "Desconhecido" - "Utilização de autorizações" - "Último acesso: %1$s\n%2$s acessos" - "Último acesso: %1$s\n%2$s acessos (%3$s em segundo plano)" + "Painel" + + Último acesso: %1$s\n%2$s acessos + Último acesso: %1$s\n%2$s acesso + + + Último acesso: %1$s\n%2$s acessos (%3$s em segundo plano) + Último acesso: %1$s\n%2$s acesso (%3$s em segundo plano) + + + Último acesso: %1$s\n%2$s acessos\nDuração: %3$s + Último acesso: %1$s\n%2$s acesso\nDuração: %3$s + + + Último acesso: %1$s\n%2$s acessos %3$s em segundo plano)\nDuração: %3$s + Último acesso: %1$s\n%2$s acesso (%3$s em segundo plano)\nDuração: %3$s + "Qualquer autorização" "Em qualquer altura" "Últimos 7 dias" @@ -135,6 +150,7 @@ "A aplicação %1$s não acedeu à sua %2$s." "Ver utilização de autorizações detalhada" "Último acesso: %1$s" + "Nunca acedida" "Permitidas" "Apenas permitido durante a utilização" "Recusadas" diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml index e97b6a9e3..4e01252d0 100644 --- a/res/values-pt/strings.xml +++ b/res/values-pt/strings.xml @@ -39,6 +39,7 @@ "Permitir apenas enquanto o app estiver em uso" "Apps" "Permissões do app" + "Gerenciador de permissões" "Não perguntar novamente" "Sem permissões" "Outras permissões" @@ -51,7 +52,7 @@ "executar uma ação desconhecida" "%1$d de %2$d apps permitidos" "Uso recente" - "Ver detalhes" + "Ver o painel de permissões" "Mostrar sistema" "Ocultar sistema" "Nenhum app" @@ -90,9 +91,23 @@ "Permissões atuais" "Promovendo app…" "Desconhecido" - "Uso de permissões" - "Último acesso: %1$s\n%2$s acessos" - "Último acesso: %1$s\n%2$s acessos (%3$s em segundo plano)" + "Painel" + + Último acesso: %1$s\n%2$s + Últimos acessos: %1$s\n%2$s + + + Último acesso: %1$s\n%2$s (%3$s em segundo plano) + Últimos acessos: %1$s\n%2$s (%3$s em segundo plano) + + + Último acesso: %1$s\n%2$s\nDuração: %3$s + Últimos acessos: %1$s\n%2$s\nDuração: %3$s + + + Último acesso: %1$s\n%2$s (%3$s em segundo plano)\nDuração: %3$s + Últimos acessos: %1$s\n%2$s (%3$s em segundo plano)\nDuração: %3$s + "Qualquer permissão" "Qualquer horário" "Últimos 7 dias" @@ -135,6 +150,7 @@ "O app %1$s não acessou seu %2$s." "Ver uso detalhado das permissões" "Último acesso: %1$s" + "Nunca acessou" "Permitido" "Permitido apenas quando em uso" "Negado" diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml index 9961e90be..6be0be9d9 100644 --- a/res/values-ro/strings.xml +++ b/res/values-ro/strings.xml @@ -39,6 +39,7 @@ "Permiteți numai când aplicația este folosită" "Aplicații" "Permisiuni pentru aplicații" + "Manager de permisiuni" "Nu mai întrebați" "Nicio permisiune" "Permisiuni suplimentare" @@ -52,7 +53,7 @@ "efectuează o acțiune necunoscută" "%1$d din %2$d aplicații au această permisiune" "Utilizare recentă" - "Vedeți detaliile" + "Vizualizați tabloul de bord pentru permisiuni" "Afișați aplicațiile de sistem" "Ascundeți aplicațiile de sistem" "Nicio aplicație" @@ -91,9 +92,27 @@ "Permisiuni actuale" "Se pregătește aplicația…" "Necunoscut" - "Folosirea permisiunilor" - "Ultima accesare: %1$s\n%2$s accesări" - "Ultima accesare: %1$s \n %2$saccesări (%3$s în fundal)" + "Tablou de bord" + + Ultima accesare: %1$s\n%2$s accesări + Ultima accesare: %1$s\n%2$s de accesări + Ultima accesare: %1$s\n%2$so accesare + + + Ultima accesare: %1$s\n%2$s accesări (%3$s în fundal) + Ultima accesare: %1$s\n%2$s de accesări (%3$s în fundal) + Ultima accesare: %1$s\n%2$so accesare (%3$s în fundal) + + + Ultima accesare: %1$s\n%2$s accesări\nDurata: %3$s + Ultima accesare: %1$s\n%2$s de accesări\nDurată: %3$s + Ultima accesare: %1$s\n%2$so accesare\nDurata: %3$s + + + Ultima accesare: %1$s\n%2$s accesări (%3$s în fundal)\nDurată: %3$s + Ultima accesare: %1$s\n%2$s de accesări (%3$s în fundal)\nDurată: %3$s + Ultima accesare: %1$s\n%2$so accesare (%3$s în fundal)\nDurată: %3$s + "Orice permisiune" "Oricând" "Ultimele 7 zile" @@ -136,6 +155,7 @@ "%1$s nu a accesat %2$s." "Afișați utilizarea detaliată a permisiunilor" "Ultima accesare: %1$s" + "Nu a fost accesată niciodată" "Permise" "Permis numai în timpul utilizării" "Respinse" diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index 60210130c..26b3a8f1c 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -39,6 +39,7 @@ "Разрешить только в активном режиме" "Приложения" "Разрешения приложений" + "Управление разрешениями" "Больше не спрашивать" "Нет разрешений" "Ещё разрешения" @@ -53,7 +54,7 @@ "выполнять неизвестное действие" "Приложений с разрешением: %1$d из %2$d" "Недавнее использование" - "Подробнее" + "Открыть панель управления разрешениями" "Показать системные процессы" "Скрыть системные процессы" "Нет приложений" @@ -92,9 +93,31 @@ "Имеющиеся разрешения" "Подождите…" "Неизвестное приложение" - "Использование разрешений" - "Последний раз использовано: %1$s.\nСколько раз использовано: %2$s." - "Последний раз использовано: %1$s.\nСколько раз использовано: %2$s (%3$s в фоновом режиме)." + "Панель управления" + + Последнее использование: %1$s.\nРазрешение использовано %2$s раз. + Последнее использование: %1$s.\nРазрешение использовано %2$s раза. + Последнее использование: %1$s.\nРазрешение использовано %2$s раз. + Последнее использование: %1$s.\nРазрешение использовано %2$s раза. + + + Последнее использование: %1$s.\nРазрешение использовано %2$s раз (%3$s в фоновом режиме). + Последнее использование: %1$s.\nРазрешение использовано %2$s раза (%3$s в фоновом режиме). + Последнее использование: %1$s.\nРазрешение использовано %2$s раз (%3$s в фоновом режиме). + Последнее использование: %1$s.\nРазрешение использовано %2$s раза (%3$s в фоновом режиме). + + + Последнее использование: %1$s.\nРазрешение использовано %2$s раз.\nПродолжительность: %3$s. + Последнее использование: %1$s.\nРазрешение использовано %2$s раза.\nПродолжительность: %3$s. + Последнее использование: %1$s.\nРазрешение использовано %2$s раз.\nПродолжительность: %3$s. + Последнее использование: %1$s.\nРазрешение использовано %2$s раза.\nПродолжительность: %3$s. + + + Последнее использование: %1$s.\nРазрешение использовано %2$s раз (%3$s в фоновом режиме).\nПродолжительность: %3$s. + Последнее использование: %1$s.\nРазрешение использовано %2$s раза (%3$s в фоновом режиме).\nПродолжительность: %3$s. + Последнее использование: %1$s.\nРазрешение использовано %2$s раз (%3$s в фоновом режиме).\nПродолжительность: %3$s. + Последнее использование: %1$s.\nРазрешение использовано %2$s раза (%3$s в фоновом режиме).\nПродолжительность: %3$s. + "Все разрешения" "Все время" "Последние 7 дней" @@ -137,6 +160,7 @@ "Приложение \"%1$s\" не обратилось к следующему разрешению: %2$s." "Показать подробную информацию об использовании разрешений" "Последний раз использовано: %1$s" + "Не использовалось." "Предоставленные разрешения" "Только когда приложение открыто" "Отсутствующие разрешения" diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml index 03585ea9a..9e43ee9b4 100644 --- a/res/values-si/strings.xml +++ b/res/values-si/strings.xml @@ -39,6 +39,7 @@ "යෙදුම භාවිතයේ දී පමණක් ඉඩ දෙන්න" "යෙදුම්" "යෙදුම් අවසර" + "අවසර කළමනාකරු" "නැවත නොඅසන්න" "අවසර නොමැත" "අතිරේක අවසර" @@ -51,7 +52,7 @@ "නොදන්නා ක්‍රියාවක් සිදු කරන්න" "යෙදුම් %1$dකින් %2$dකට ඉඩ දෙන ලදී" "මෑත භාවිතය" - "විස්තර බලන්න" + "අවසර උපකරණ පුවරුව බලන්න" "පද්ධතිය පෙන්වන්න" "පද්ධතිය සඟවන්න" "යෙදුම් නොමැත" @@ -90,9 +91,23 @@ "වත්මන් අවසර" "යෙදුම වේදිකාගත කරමින්..." "නොදනී" - "අවසර භාවිතය" - "අවසන් ප්‍රවේශය: ප්‍රවේශයන් %1$s\n%2$s" - "අවසන් ප්‍රවේශය: ප්‍රවේශයන් %1$s\n%2$s (පසුබිමෙහි %3$s)" + "උපකරණ පුවරුව" + + අවසන් ප්‍රවේශය: ප්‍රවේශ %1$s\n%2$sක් + අවසන් ප්‍රවේශය: ප්‍රවේශ %1$s\n%2$sක් + + + අවසන් ප්‍රවේශය: ප්‍රවේශ %1$s\n%2$sක් (පසුබිම තුළ %3$s) + අවසන් ප්‍රවේශය: ප්‍රවේශ %1$s\n%2$sක් (පසුබිම තුළ %3$s) + + + අවසන් ප්‍රවේශය: ප්‍රවේශ %1$s\n%2$sක්\nකාලය: %3$s + අවසන් ප්‍රවේශය: ප්‍රවේශ %1$s\n%2$sක්\nකාලය: %3$s + + + අවසන් ප්‍රවේශය: ප්‍රවේශ %1$s\n%2$sක් (පසුබිම තුළ %3$s)\nකාලය: %3$s + අවසන් ප්‍රවේශය: ප්‍රවේශ %1$s\n%2$sක් (පසුබිම තුළ %3$s)\nකාලය: %3$s + "ඕනෑම අවසරයක්" "ඕනෑම වේලාවක" "පසුගිය දින 7" @@ -135,6 +150,7 @@ "%1$s ඔබේ %2$s වෙත පිවිස නැත." "විස්තරාත්මක අවසර භාවිතය බලන්න" "අවසන් ප්‍රවේශය: %1$s" + "කිසි විටෙක ප්‍රවේශ නොවූ" "ඉඩ දුන්" "භාවිත කෙරෙන විට පමණක් අනුමත කෙරේ" "ප්‍රතික්ෂේපයි" diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml index e64f1380d..c787d2c12 100644 --- a/res/values-sk/strings.xml +++ b/res/values-sk/strings.xml @@ -39,6 +39,7 @@ "Povoliť iba počas používania aplikácie" "Aplikácie" "Povolenia aplikácií" + "Správca povolení" "Nabudúce sa nepýtať" "Žiadne povolenia" "Ďalšie povolenia" @@ -53,7 +54,7 @@ "umožňuje vykonať neznámu akciu" "Povolené: %1$d%2$d aplikácií" "Nedávne využitie" - "Zobraziť podrobnosti" + "Zobraziť hlavný panel povolení" "Zobraziť systémové" "Skryť systémové" "Žiadne aplikácie" @@ -92,9 +93,31 @@ "Aktuálne povolenia" "Aplikácia je zavádzaná po etapách…" "Neznáme" - "Využitie povolení" - "Posledný prístup: %1$s\npočet prístupov: %2$s" - "Posledný prístup: %1$s\npočet prístupov: %2$s (%3$s na pozadí)" + "Hlavný panel" + + Posledný prístup: %1$s\n%2$s prístupy + Posledný prístup: %1$s\n%2$s accesses + Posledný prístup: %1$s\n%2$s prístupov + Posledný prístup: %1$s\n%2$s prístup + + + Posledný prístup: %1$s\n%2$s prístupy (%3$s na pozadí) + Posledný prístup: %1$s\n%2$s accesses (%3$s in background) + Posledný prístup: %1$s\n%2$s prístupov (%3$s na pozadí) + Posledný prístup: %1$s\n%2$s prístup (%3$s na pozadí) + + + Posledný prístup: %1$s\n%2$s prístupy\nTrvanie: %3$s + Posledný prístup: %1$s\n%2$s accesses\nDuration: %3$s + Posledný prístup: %1$s\n%2$s prístupov\nTrvanie: %3$s + Posledný prístup: %1$s\n%2$s prístup\nTrvanie: %3$s + + + Posledný prístup: %1$s\n%2$s prístupy (%3$s na pozadí)\nTrvanie: %3$s + Posledný prístup: %1$s\n%2$s accesses (%3$s in background)\nDuration: %3$s + Posledný prístup: %1$s\n%2$s prístupov (%3$s na pozadí)\nTrvanie: %3$s + Posledný prístup: %1$s\n%2$s prístup (%3$s na pozadí)\nTrvanie: %3$s + "Všetky povolenia" "Kedykoľvek" "Posledných 7 dní" @@ -137,6 +160,7 @@ "%1$s nemôže používať povolenie %2$s." "Zobraziť podrobné údaje o využití povolení" "Posledný prístup: %1$s" + "Prístup sa nikdy neuskutočnil" "Povolené" "Povolené iba počas používania" "Zamietnuté" @@ -181,8 +205,8 @@ "Nastavenia" "%s má úplný prístup do vášho zariadenia" "Služby dostupnosti s úplným prístupom do vášho zariadenia: %s" - "%s si môže zobraziť vašu obrazovku, akcie a vstupy, vykonávať akcie a ovládať zobrazenie." - "Tieto služby si môžu zobraziť vašu obrazovku, akcie a vstupy, vykonávať akcie a ovládať zobrazenie." + "%s si môže zobraziť vašu obrazovku, akcie a vstupy, vykonávať akcie a ovládať obrazovku." + "Tieto služby si môžu zobraziť vašu obrazovku, akcie a vstupy, vykonávať akcie a ovládať obrazovku." "Predvolené aplikácie" "Žiadne predvolené aplikácie" "Predvolené na prácu" diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml index ad17c800b..993ed704d 100644 --- a/res/values-sl/strings.xml +++ b/res/values-sl/strings.xml @@ -39,6 +39,7 @@ "Dovoli samo, ko je aplikacija v uporabi" "Aplikacije" "Dovoljenja za aplikacije" + "Upravitelj dovoljenj" "Ne sprašuj več" "Ni dovoljenj" "Dodatna dovoljenja" @@ -53,7 +54,7 @@ "izvedba neznanega dejanja" "Dovoljene aplikacije: %1$d od %2$d" "Nedavna uporaba" - "Ogled podrobnosti" + "Nadzorna plošča dovoljenj" "Prikaz sistemskih procesov" "Skrivanje sistemskih procesov" "Ni aplikacij" @@ -92,9 +93,31 @@ "Trenutna dovoljenja" "Priprava aplikacije …" "Neznano" - "Uporaba dovoljenj" - "Zadnji dostop: %1$s\nŠt. dostopov: %2$s" - "Zadnji dostop: %1$s\nŠt. dostopov: %2$s (%3$s v ozadju)" + "Nadzorna plošča" + + Zadnji dostop: %1$s\n%2$s dostop + Zadnji dostop: %1$s\n%2$s dostopa + Zadnji dostop: %1$s\n%2$s dostopi + Zadnji dostop: %1$s\n%2$s dostopov + + + Zadnji dostop: %1$s\n%2$s dostop (%3$s v ozadju) + Zadnji dostop: %1$s\n%2$s dostopa (%3$s v ozadju) + Zadnji dostop: %1$s\n%2$s dostopi (%3$s v ozadju) + Zadnji dostop: %1$s\n%2$s dostopov (%3$s v ozadju) + + + Zadnji dostop: %1$s\n%2$s dostop\nTrajanje: %3$s + Zadnji dostop: %1$s\n%2$s dostopa\nTrajanje: %3$s + Zadnji dostop: %1$s\n%2$s dostopi\nTrajanje: %3$s + Zadnji dostop: %1$s\n%2$s dostopov\nTrajanje: %3$s + + + Zadnji dostop: %1$s\n%2$s dostop (%3$s v ozadju)\nTrajanje: %3$s + Zadnji dostop: %1$s\n%2$s dostopa (%3$s v ozadju)\nTrajanje: %3$s + Zadnji dostop: %1$s\n%2$s dostopi (%3$s v ozadju)\nTrajanje: %3$s + Zadnji dostop: %1$s\n%2$s dostopov (%3$s v ozadju)\nTrajanje: %3$s + "Katero koli dovoljenje" "Kadar koli" "Zadnjih 7 dni" @@ -137,6 +160,7 @@ "Aplikacija %1$s ni dostopila do: %2$s." "Podroben prikaz uporabe dovoljenj" "Zadnji dostop: %1$s" + "Še brez dostopa" "Dovoljeno" "Dovoljeno samo med uporabo" "Zavrnjeno" diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml index 914d01667..1dcbf0236 100644 --- a/res/values-sq/strings.xml +++ b/res/values-sq/strings.xml @@ -39,6 +39,7 @@ "Lejo vetëm kur aplikacioni është në përdorim" "Aplikacionet" "Lejet e aplikacionit" + "Menaxheri i lejeve" "Mos pyet më" "Nuk ka leje" "Lejet shtesë" @@ -51,7 +52,7 @@ "kryej një veprim të panjohur" "%1$d nga %2$d aplikacione u lejuan" "Përdorimi së fundi" - "Shiko detajet" + "Shiko panelin e lejeve" "Shfaq sistemin" "Fshih sistemin" "Asnjë aplikacion" @@ -90,9 +91,23 @@ "Lejet aktuale" "Po vihet në përdorim aplikacioni..." "I panjohur" - "Përdorimi i lejeve" - "Qasja e fundit: %1$s\n%2$s qasje" - "Qasja e fundit: %1$s\n%2$s qasje (%3$s në sfond)" + "Paneli analitik" + + Qasja e fundit: %1$s\n%2$s qasje + Qasja e fundit: %1$s\n%2$s qasje + + + Qasja e fundit: %1$s\n%2$s qasje (%3$s në sfond) + Qasja e fundit: %1$s\n%2$s qasje (%3$s në sfond) + + + Qasja e fundit: %1$s\n%2$s qasje\nKohëzgjatja: %3$s + Qasja e fundit: %1$s\n%2$s qasje\nKohëzgjatja: %3$s + + + Qasja e fundit: %1$s\n%2$s qasje (%3$s në sfond)\nKohëzgjatja: %3$s + Qasja e fundit: %1$s\n%2$s qasje (%3$s në sfond)\nKohëzgjatja: %3$s + "Çdo autorizim" "Në çdo kohë" "7 ditët e fundit" @@ -135,6 +150,7 @@ "%1$s nuk ka pasur qasje te %2$s." "Shiko përdorimin e detajuar të autorizimeve" "Qasja e fundit: %1$s" + "Nuk ka asnjë qasje" "Të lejuara" "Lejohet vetëm kur është në përdorim" "Të refuzuara" diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml index 30dddb4c1..0ff6da5df 100644 --- a/res/values-sr/strings.xml +++ b/res/values-sr/strings.xml @@ -39,6 +39,7 @@ "Дозволи само док се апликација користи" "Апликације" "Дозволе за апликације" + "Менаџер дозвола" "Не питај поново" "Нема дозвола" "Додатне дозволе" @@ -52,7 +53,7 @@ "обавља непознату радњу" "Апликације са дозволом: %1$d од %2$d" "Недавна употреба" - "Прикажи детаље" + "Прикажи контролну таблу за дозволе" "Прикажи системске" "Сакриј системске" "Нема апликација" @@ -91,9 +92,27 @@ "Актуелне дозволе" "Апликација се припрема…" "Непознато" - "Коришћење дозвола" - "Последњи приступ: %1$s\n%2$s приступа" - "Последњи приступ: %1$s\n%2$s приступа (%3$s у позадини)" + "Контролна табла" + + Последњи приступ: %1$s\n%2$s приступ + Последњи приступ: %1$s\n%2$s приступа + Последњи приступ: %1$s\n%2$s приступа + + + Последњи приступ: %1$s\n%2$s приступ (%3$s у позадини) + Последњи приступ: %1$s\n%2$s приступа (%3$s у позадини) + Последњи приступ: %1$s\n%2$s приступа (%3$s у позадини) + + + Последњи приступ: %1$s\n%2$s приступ\nТрајање: %3$s + Последњи приступ: %1$s\n%2$s приступа\nТрајање: %3$s + Последњи приступ: %1$s\n%2$s приступа\nТрајање: %3$s + + + Последњи приступ: %1$s\n%2$s приступ (%3$s у позадини)\nТрајање: %3$s + Последњи приступ: %1$s\n%2$s приступа (%3$s у позадини)\nТрајање: %3$s + Последњи приступ: %1$s\n%2$s приступа (%3$s у позадини)\nТрајање: %3$s + "Било која дозвола" "Било када" "Последњих 7 дана" @@ -136,6 +155,7 @@ "Апликација %1$s није приступила дозволи %2$s." "Прегледајте детаљне дозволе за коришћење" "Последњи приступ: %1$s" + "Без приступа" "Дозвољено" "Дозвољено само док се апликација користи" "Одбијено" diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml index 2f1614bd4..dfdc06567 100644 --- a/res/values-sv/strings.xml +++ b/res/values-sv/strings.xml @@ -39,6 +39,7 @@ "Tillåt bara när appen används" "Appar" "Appbehörigheter" + "Behörighetshantering" "Fråga inte igen" "Inga behörigheter" "Ytterligare behörigheter" @@ -51,7 +52,7 @@ "utför en okänd åtgärd" "%1$d av %2$d appar tillåts" "Senaste användningen" - "Visa information" + "Visa behörighetsöversikt" "Visa systemet" "Dölj systemet" "Inga appar" @@ -90,9 +91,23 @@ "Nuvarande behörighet" "Provkör appen …" "Okänd" - "Behörighetsanvändning" - "Användes senast: %1$s\n%2$s åtkomster" - "Användes senast: %1$s\n%2$s åtkomster (%3$s i bakgrunden)" + "Översikt" + + Senaste åtkomst: %1$s\n%2$s åtkomster + Senaste åtkomst: %1$s\n%2$s åtkomst + + + Senaste åtkomst: %1$s\n%2$s åtkomster (%3$s i bakgrunden) + Senaste åtkomst: %1$s\n%2$s åtkomst (%3$s i bakgrunden) + + + Senaste åtkomst: %1$s\n%2$s åtkomster\nVaraktighet: %3$s + Senaste åtkomst: %1$s\n%2$s åtkomst\nVaraktighet: %3$s + + + Senaste åtkomst: %1$s\n%2$s åtkomster (%3$s i bakgrunden)\nVaraktighet: %3$s + Senaste åtkomst: %1$s\n%2$s åtkomst (%3$s i bakgrunden)\nVaraktighet: %3$s + "Alla behörigheter" "När som helst" "Senaste 7 dagarna" @@ -135,6 +150,7 @@ "%1$s har inte fått åtkomst till %2$s." "Visa utförlig information om behörighetsanvändning" "Användes senast: %1$s" + "Aldrig använd" "Tillåts" "Tillåt bara vid användning" "Nekas" diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml index 496ee7166..74d5d9837 100644 --- a/res/values-sw/strings.xml +++ b/res/values-sw/strings.xml @@ -39,6 +39,7 @@ "Ruhusu tu wakati programu inatumika" "Programu" "Ruhusa za programu" + "Kidhibiti cha ruhusa" "Usiniulize tena" "Hakuna ruhusa" "Ruhusa za ziada" @@ -51,7 +52,7 @@ "kutekeleza kitendo kisichojulikana" "Inaruhusu programu %1$d kati ya %2$d" "Matumizi ya hivi majuzi" - "Angalia maelezo" + "Angalia Dashibodi ya Ruhusa" "Onyesha mfumo" "Ficha mfumo" "Hakuna programu" @@ -90,9 +91,23 @@ "Ruhusa zilizopo" "Inatayarisha programu…" "Haijulikani" - "Matumizi ya ruhusa" - "Imetumiwa mwisho: %1$s\nimetumiwa mara %2$s" - "Imetumiwa mwisho: %1$s\nimetumiwa mara %2$s(mara %3$s chinichini)" + "Dashibodi" + + Mwisho kutumiwa: %1$s\n imetumia mara %2$s + Mwisho kutumiwa: %1$s\nimetumia mara %2$s + + + Mwisho kutumiwa: %1$s\nimetumiwa mara %2$s(mara %3$s chinichini) + Mwisho kutumiwa: %1$s\n imetumiwa mara %2$s (mara %3$s chinichini) + + + Mwisho kutumiwa: %1$s\n imetumiwa mara %2$s \nMuda: %3$s + Mwisho kutumiwa: %1$s\n imetumiwa mara %2$s\nMuda: %3$s + + + Mwisho kutumiwa: %1$s\n imetumia mara %2$s (mara %3$s chinichini \nMuda: %3$s + Mwisho kutumiwa: %1$s\n imetumiwa mara %2$s (mara %3$s chinichini)\nMuda: %3$s + "Ruhusa yoyote" "Wakati wowote" "Siku 7 zilizopita" @@ -135,6 +150,7 @@ "%1$s haijafikia %2$s yako." "Angalia matumizi ya ruhusa za kina" "Imetumiwa mwisho: %1$s" + "Haijawahi kutumiwa" "Zinazoruhusiwa" "Inaruhusiwa tu wakati inatumika" "Imekataliwa" diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml index 57daa0d59..e802161d7 100644 --- a/res/values-ta/strings.xml +++ b/res/values-ta/strings.xml @@ -39,6 +39,8 @@ "ஆப்ஸ் உபயோகத்தில் இருக்கும்போது மட்டும் அனுமதி" "ஆப்ஸ்" "ஆப்ஸ் அனுமதிகள்" + + "மீண்டும் கேட்காதே" "அனுமதிகள் தேவையில்லை" "கூடுதல் அனுமதிகள்" @@ -51,7 +53,8 @@ "அறியப்படாத செயலைச் செய்யும்" "அனுமதிக்கப்பட்ட ஆப்ஸ்: %1$d/%2$d" "சமீபத்திய உபயோகம்" - "விவரங்களைக் காட்டு" + + "சிஸ்டம் ஆப்ஸைக் காட்டு" "சிஸ்டம் ஆப்ஸை மறை" "எந்த ஆப்ஸிற்கும் தேவையில்லை" @@ -90,9 +93,12 @@ "தற்போதைய அனுமதிகள்" "ஆப்ஸ் தயாராகிறது…" "தெரியாதது" - "அனுமதிகள் உபயோகம்" - "கடைசியாகப் பயன்படுத்தியது: %1$s\n%2$s அணுகல்கள்" - "கடைசியாகப் பயன்படுத்தியது: %1$s\n%2$s அணுகல்கள் (பின்புலத்தில்: %3$s)" + + + + + + "அனுமதி எதுவாயினும்" "எந்த நேரமும்" "கடந்த 7 நாட்கள்" @@ -135,6 +141,8 @@ "%1$s உங்கள் %2$s அனுமதியைப் பயன்படுத்தவில்லை." "அனுமதிகளின் உபயோகம் தொடர்பான விவரங்களைக் காட்டு" "கடைசியாகப் பயன்படுத்தியது: %1$s" + + "அனுமதிக்கப்பட்டவை" "உபயோகத்தில் மட்டுமே அனுமதிக்கப்படும்" "மறுக்கப்பட்டது" @@ -168,16 +176,11 @@ "திற" "நிறுவல் நீக்கு" "உடனே நிறுத்து" - - - - - - - - - - + "அமைப்புகள்" + "உங்கள் சாதனத்திற்கான முழு அணுகல் %s சேவைக்கு உள்ளது" + "உங்கள் சாதனத்திற்கான முழு அணுகல் %s அணுகல்தன்மை சேவைகளுக்கு உள்ளது" + "உங்கள் திரை, செயல்கள் மற்றும் உள்ளீடுகளைப் பார்க்கவும், செயல்களை நிறைவேற்றவும், காட்சியைக் கட்டுப்படுத்தவும் %s சேவையால் இயலும்." + "உங்கள் திரை, செயல்கள் மற்றும் உள்ளீடுகளைப் பார்க்கவும், செயல்களை நிறைவேற்றவும், காட்சியைக் கட்டுப்படுத்தவும் இந்தச் சேவைகளால் இயலும்." "இயல்புநிலை ஆப்ஸ்" "இயல்புநிலை ஆப்ஸ் இல்லை" "பணிக்கான இயல்பு நிலை ஆப்ஸ்" @@ -199,11 +202,9 @@ "அழைப்புத் திரை ஆப்ஸ்" "அழைப்புக்கான கம்பேனியன் ஆப்ஸ்" "கார் காட்சிப்படுத்தல் ஆப்ஸ்" - - + "பணிக் கணக்கிற்கான ஆதரவு இதில் இல்லை" "கவனத்திற்கு: திரைப் பூட்டு அமைக்கப்பட்டிருக்கும் நிலையில் உங்கள் மொபைலை மீண்டும் தொடங்கினால் அன்லாக் செய்யப்படும்வரை இந்த ஆப்ஸ் இயங்காது." - - + "திரையில் தெரியும் தகவல் அல்லது ஆப்ஸிற்குள் அணுகக்கூடிய தகவல் உட்பட உங்கள் சிஸ்டத்தில் செயல்பாட்டிலுள்ள ஆப்ஸ் பற்றிய தகவல்களை அசிஸ்டண்ட்டால் படிக்க இயலும்." "பிழைதிருத்தத் தரவைப் பகிர்தல்" "விரிவான பிழைதிருத்தத் தகவலைப் பகிரவா?" "பிழைதிருத்தத் தகவலை %1$s பதிவேற்ற விரும்புகிறது." diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml index 8f258db42..9d4fade1d 100644 --- a/res/values-te/strings.xml +++ b/res/values-te/strings.xml @@ -39,6 +39,7 @@ "యాప్ వినియోగంలో ఉన్నప్పుడు మాత్రమే అనుమతించు" "యాప్‌లు" "యాప్ అనుమతులు" + "అనుమతి మేనేజర్" "మళ్లీ అడగవద్దు" "అనుమతులు లేవు" "అదనపు అనుమతులు" @@ -51,7 +52,7 @@ "తెలియని చర్యను చేస్తుంది" "%2$dలో %1$d యాప్‌లు అనుమతించబడ్డాయి" "ఇటీవలి వినియోగం" - "వివరాలను చూడండి" + "అనుమతుల డాష్‌బోర్డ్‌ను చూడండి" "సిస్టమ్‌ను చూపు" "సిస్టమ్ దాచు" "యాప్‌లు లేవు" @@ -90,9 +91,23 @@ "ప్రస్తుత అనుమతులు" "యాప్‌ను అందిస్తోంది…" "తెలియదు" - "అనుమతుల వినియోగం" - "చివరి యాక్సెస్: %1$s\n%2$s యాక్సెస్‌లు" - "చివరి యాక్సెస్: %1$s\n%2$s (%3$s in నేపథ్యంలో)ని యాక్సెస్ చేస్తుంది" + "డాష్‌బోర్డ్" + + చివరి యాక్సెస్: %1$s\n%2$s యాక్సెస్‌లు + చివరి యాక్సెస్: %1$s\n%2$s యాక్సెస్ + + + చివరి యాక్సెస్: %1$s\n%2$s యాక్సెస్‌లు (నేపథ్యంలో %3$s) + చివరి యాక్సెస్: %1$s\n%2$s యాక్సెస్ (నేపథ్యంలో %3$s) + + + చివరి యాక్సెస్: %1$s\n%2$s యాక్సెస్‌లు\nవ్యవధి: %3$s + చివరి యాక్సెస్: %1$s\n%2$s యాక్సెస్\nవ్యవధి: %3$s + + + చివరి యాక్సెస్: %1$s\n%2$s యాక్సెస్‌లు (నేపథ్యంలో %3$s)\nవ్యవధి: %3$s + చివరి యాక్సెస్: %1$s\n%2$s యాక్సెస్ (నేపథ్యంలో %3$s)\nవ్యవధి: %3$s + "ఏ అనుమతి అయినా" "ఎప్పుడైనా" "గత 7 రోజులు" @@ -135,6 +150,7 @@ "%1$s మీ %2$sని ఉపయోగించలేదు." "వివరణాత్మక అనుమతుల వినియోగాన్ని చూడండి" "చివరిసారి యాక్సెస్ చేసింది: %1$s" + "ఎప్పుడూ యాక్సెస్ చేయలేదు" "అనుమతించినవి" "ఉపయోగించేటప్పుడు మాత్రమే అనుమతివ్వబడును" "తిరస్కరించినవి" @@ -168,16 +184,11 @@ "తెరవండి" "అన్ఇన్‌స్టాల్ చేయి" "ఫోర్స్ స్టాప్" - - - - - - - - - - + "సెట్టింగ్‌లు" + "%s మీ పరికరానికి పూర్తి యాక్సెస్ కలిగి ఉంది" + "%s యాక్సెసబిలిటీ సేవలు మీ పరికరానికి పూర్తి యాక్సెస్ కలిగి ఉన్నాయి" + "%s మీ స్క్రీన్, చర్యలు మరియు ఇన్‌పుట్‌లను చూడగలదు, చర్యలను అమలు చేయగలదు, అలాగే ప్రదర్శనను నియంత్రించగలదు." + "ఈ సేవలు మీ స్క్రీన్, చర్యలు మరియు ఇన్‌పుట్‌లను చూడగలవు, చర్యలను అమలు చేయగలవు మరియు ప్రదర్శనను నియంత్రించగలవు." "డిఫాల్ట్ యాప్‌లు" "డిఫాల్ట్ యాప్‌లు ఏవీ లేవు" "కార్యాలయం కోసం డిఫాల్ట్" @@ -199,11 +210,9 @@ "కాల్ స్క్రీనింగ్ యాప్" "కాల్ సహచర యాప్" "కార్ ప్రొజెక్షన్ యాప్" - - + "కార్యాలయ ప్రొఫైల్‌కు మద్దతు ఇవ్వదు" "చిన్న గమనిక: మీరు భద్రత కోసం స్క్రీన్ లాక్‌ని సెటప్‌ చేసి పెట్టుకున్నారు పైగా మీ పరికరాన్ని పునఃప్రారంభించినట్టున్నారు కనుక స్క్రీన్ లాక్ అయ్యిపోయింది. మీరు పాస్‌వర్డ్‌ని నమోదు చేసేవరకూ ఈ యాప్ ప్రారంభం కాదు." - - + "మీ స్క్రీన్‌పై కనిపించే లేదా యాప్‌లలో యాక్సెస్ చేసే సమాచారంతో పాటు అసిస్టెంట్ మీ సిస్టమ్‌లో వినియోగంలో ఉన్న యాప్‌ల గురించిన సమాచారాన్ని చదవగలుగుతుంది." "డీబగ్గింగ్ డేటాను షేర్ చేయండి" "వివరణాత్మక డీబగ్గింగ్ డేటాను షేర్ చేయాలా?" "%1$sడీబగ్గింగ్ సమాచారాన్ని అప్‌లో డ్ చేయదలుచుకుంటున్నారు." diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml index 41f2508c9..f27c33829 100644 --- a/res/values-th/strings.xml +++ b/res/values-th/strings.xml @@ -39,6 +39,7 @@ "อนุญาตเมื่อมีการใช้แอปเท่านั้น" "แอป" "สิทธิ์ของแอป" + "เครื่องมือจัดการสิทธิ์" "ไม่ต้องถามอีก" "ไม่มีสิทธิ์" "สิทธิ์เพิ่มเติม" @@ -51,7 +52,7 @@ "ดำเนินการทำงานที่ไม่รู้จัก" "อนุญาตแล้ว %1$d จาก %2$d แอป" "การใช้งานล่าสุด" - "ดูรายละเอียด" + "ดูหน้าแดชบอร์ดของสิทธิ์" "แสดงระบบ" "ซ่อนระบบ" "ไม่มีแอป" @@ -90,9 +91,23 @@ "สิทธิ์ปัจจุบัน" "กำลังปรับสภาพแวดล้อมของแอป…" "ไม่ทราบ" - "การใช้สิทธิ์" - "เข้าถึงล่าสุด: การเข้าถึง %1$s\n%2$s รายการ" - "เข้าถึงล่าสุด: การเข้าถึง %1$s\n%2$s รายการ (%3$s รายการในพื้นหลัง)" + "หน้าแดชบอร์ด" + + เข้าถึงล่าสุด: การเข้าถึง %1$s\n%2$s รายการ + เข้าถึงล่าสุด: การเข้าถึง %1$s\n%2$s รายการ + + + เข้าถึงล่าสุด: การเข้าถึง %1$s\n%2$s รายการ (%3$s รายการในพื้นหลัง) + เข้าถึงล่าสุด: การเข้าถึง %1$s\n%2$s รายการ (%3$s รายการในพื้นหลัง) + + + เข้าถึงล่าสุด: การเข้าถึง %1$s\n%2$s รายการ\nระยะเวลา: %3$s + เข้าถึงล่าสุด: การเข้าถึง %1$s\n%2$s รายการ\nระยะเวลา: %3$s + + + เข้าถึงล่าสุด: การเข้าถึง %1$s\n%2$s รายการ (%3$s รายการในพื้นหลัง)\nระยะเวลา: %3$s + เข้าถึงล่าสุด: การเข้าถึง %1$s\n%2$s รายการ (%3$s รายการในพื้นหลัง)\nระยะเวลา: %3$s + "สิทธิ์ใดก็ได้" "ทุกเวลา" "7 วันที่ผ่านมา" @@ -135,6 +150,7 @@ "%1$s ไม่ได้เข้าถึง %2$s ของคุณ" "ดูรายละเอียดการใช้สิทธิ์" "เข้าถึงล่าสุด: %1$s" + "ไม่เคยเข้าถึง" "ได้รับอนุญาตแล้ว" "อนุญาตขณะใช้งานอยู่เท่านั้น" "ถูกปฏิเสธ" @@ -168,16 +184,11 @@ "เปิด" "ถอนการติดตั้ง" "บังคับให้หยุด" - - - - - - - - - - + "การตั้งค่า" + "%s มีสิทธิ์เข้าถึงอุปกรณ์ได้โดยสมบูรณ์" + "บริการช่วยเหลือพิเศษ %s รายการมีสิทธิ์เข้าถึงอุปกรณ์ได้โดยสมบูรณ์" + "%s จะดูหน้าจอ การทำงาน และอินพุตของคุณได้ รวมถึงดำเนินการต่างๆ และควบคุมหน้าจอ" + "บริการเหล่านี้จะดูหน้าจอ การทำงาน และอินพุตของคุณได้ รวมถึงดำเนินการต่างๆ และควบคุมหน้าจอ" "แอปเริ่มต้น" "ไม่มีแอปเริ่มต้น" "ค่าเริ่มต้นสำหรับงาน" @@ -199,11 +210,9 @@ "แอปสกรีนสายเรียกเข้า" "แอปที่ใช้ร่วมกับการโทร" "แอป Car Projection" - - + "ไม่รองรับโปรไฟล์งาน" "หมายเหตุ: หากคุณรีสตาร์ทอุปกรณ์และตั้งการล็อกหน้าจอไว้ แอปนี้จะเริ่มทำงานไม่ได้จนกว่าคุณจะปลดล็อกอุปกรณ์" - - + "Assistant จะอ่านข้อมูลเกี่ยวกับแอปที่ใช้งานอยู่ในระบบของคุณได้ รวมถึงข้อมูลที่ปรากฏบนหน้าจอหรือที่เข้าถึงได้ภายในแอป" "แชร์ข้อมูลการแก้ไขข้อบกพร่อง" "แชร์ร์ข้อมูลการแก้ไขข้อบกพร่องโดยละเอียดไหม" "%1$s ต้องการอัปโหลดข้อมูลการแก้ไขข้อบกพร่อง" diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml index 328058806..2775b3b97 100644 --- a/res/values-tl/strings.xml +++ b/res/values-tl/strings.xml @@ -39,6 +39,7 @@ "Payagan lang habang ginagamit ang app" "Mga App" "Mga pahintulot sa app" + "Manager ng pahintulot" "Huwag nang itanong muli" "Walang pahintulot" "Mga karagdagang pahintulot" @@ -51,7 +52,7 @@ "magsagawa ng hindi kilalang pagkilos" "Pinapayagan ang %1$d sa %2$d (na) app" "Kamakailang paggamit" - "Tingnan ang mga detalye" + "Tingnan ang Dashboard ng Mga Pahintulot" "Ipakita ang system" "Itago ang system" "Walang app" @@ -90,9 +91,23 @@ "Mga kasalukuyang pahintulot" "Inihahanda ang app…" "Hindi alam" - "Paggamit ng mga pahintulot" - "Huling pag-access: %1$s\n%2$s (na) pag-access" - "Huling pag-access: %1$s\n%2$s (na) pag-access (%3$s sa background)" + "Dashboard" + + Huling pag-access: %1$s\n%2$s pag-access + Huling pag-access: %1$s\n%2$s na pag-access + + + Huling pag-access: %1$s\n%2$s pag-access (%3$s sa background) + Huling pag-access: %1$s\n%2$s na pag-access (%3$s sa background) + + + Huling pag-access: %1$s\n%2$s pag-access\nTagal: %3$s + Huling pag-access: %1$s\n%2$s na pag-access\nTagal: %3$s + + + Huling pag-access: %1$s\n%2$s pag-access (%3$s sa background)\nTagal: %3$s + Huling pag-access: %1$s\n%2$s na pag-access (%3$s sa background)\nTagal: %3$s + "Anumang pahintulot" "Anumang oras" "Nakalipas na 7 araw" @@ -135,6 +150,7 @@ "Hindi na-access ng %1$s ang iyong %2$s." "Tingnan ang detalyadong paggamit sa mga pahintulot" "Huling na-access: %1$s" + "Hindi na-access kahit kailan" "Pinapayagan" "Pinapayagan lang habang ginagamit" "Tinanggihan" diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml index 25a59d05e..7c345f0e5 100644 --- a/res/values-tr/strings.xml +++ b/res/values-tr/strings.xml @@ -39,6 +39,7 @@ "Yalnızca uygulama kullanılırken izin ver" "Uygulamalar" "Uygulama izinleri" + "İzin yöneticisi" "Tekrar sorma" "İzin yok" "Ek izinler" @@ -51,7 +52,7 @@ "bilinmeyen bir işlem gerçekleştirme" "%1$d / %2$d uygulamaya izin veriliyor" "Son kullanım" - "Ayrıntıları göster" + "İzin Kontrol Panelini göster" "Sistemi göster" "Sistemi gizle" "Uygulama yok" @@ -90,9 +91,23 @@ "Geçerli izinler" "Uygulama hazırlanıyor…" "Bilinmiyor" - "İzin kullanımı" - "Son erişim: %1$s - \n %2$s erişim" - "Son erişim: %1$s - \n %2$s erişim (%3$s erişim arka planda)" + "Kontrol paneli" + + Son erişim: %1$s\n%2$s erişim + Son erişim: %1$s\n%2$s erişim + + + Son erişim: %1$s - \n %2$s erişim (arka planda %3$s erişim) + Son erişim: %1$s\n%2$s erişim (arka planda %3$serişim) + + + Son erişim: %1$s\n%2$s erişim\nSüre: %3$s + Son erişim: %1$s\n%2$s erişim\nSüre: %3$s + + + Son erişim: %1$s\n%2$s erişim (arka planda %3$s erişim)\nSüre: %3$s + Son erişim: %1$s\n%2$s erişim (arka planda %3$s erişim)\nSüre: %3$s + "Tüm izinler" "Her zaman" "Son 7 gün" @@ -135,6 +150,7 @@ "%1$s, %2$s izninize erişmedi." "Ayrıntılı izin kullanımını göster" "Son erişim:%1$s" + "Hiç erişilmedi" "İzin verildi" "Yalnızca kullanımdayken izin verilenler" "Reddedildi" diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml index 3baa55e33..fc3834975 100644 --- a/res/values-uk/strings.xml +++ b/res/values-uk/strings.xml @@ -39,6 +39,7 @@ "Дозволяти, лише коли додаток використовується" "Додатки" "Дозволи додатка" + "Диспетчер дозволів" "Більше не запитувати" "Немає дозволів" "Додаткові дозволи" @@ -53,7 +54,7 @@ "виконувати невідому дію" "Додатки з дозволом: %1$d з %2$d" "Нещодавно використано" - "Докладніше" + "Переглянути панель дозволів" "Показати системні додатки" "Сховати системні додатки" "Немає додатків" @@ -92,9 +93,31 @@ "Поточні дозволи" "Підготовка додатка…" "Невідомо" - "Використання дозволів" - "Останній сеанс доступу: %1$s\nСеансів доступу: %2$s" - "Останній сеанс доступу: %1$s\nСеансів доступу: %2$s (%3$s у фоновому режимі)" + "Інформаційна панель" + + Останні сеанси доступу: %1$s\n%2$s сеанс + Останні сеанси доступу: %1$s\n%2$s сеанси + Останні сеанси доступу: %1$s\n%2$s сеансів + Останні сеанси доступу: %1$s\n%2$s сеансу + + + Останні сеанси доступу: %1$s\n%2$s сеанс (%3$s у фоновому режимі) + Останні сеанси доступу: %1$s\n%2$s сеанси (%3$s у фоновому режимі) + Останні сеанси доступу: %1$s\n%2$s сеансів (%3$s у фоновому режимі) + Останні сеанси доступу: %1$s\n%2$s сеансу (%3$s у фоновому режимі) + + + Останні сеанси доступу: %1$s\n%2$s сеанс\nТривалість: %3$s + Останні сеанси доступу: %1$s\n%2$s сеанси\nТривалість: %3$s + Останні сеанси доступу: %1$s\n%2$s сеансів\nТривалість: %3$s + Останні сеанси доступу: %1$s\n%2$s сеансу\nТривалість: %3$s + + + Останні сеанси доступу: %1$s\n%2$s сеанс (%3$s у фоновому режимі)\nТривалість: %3$s + Останні сеанси доступу: %1$s\n%2$s сеанси (%3$s у фоновому режимі)\nТривалість: %3$s + Останні сеанси доступу: %1$s\n%2$s сеансів (%3$s у фоновому режимі)\nТривалість: %3$s + Останні сеанси доступу: %1$s\n%2$s сеансу (%3$s у фоновому режимі)\nТривалість: %3$s + "Будь-який дозвіл" "У будь-який час" "Останні 7 днів" @@ -137,6 +160,7 @@ "%1$s не приймає дозвіл \"%2$s\"." "Переглянути детальну інформацію про використання дозволів" "Останній сеанс доступу: %1$s" + "Не отримував доступу" "Дозволено" "Дозволено лише за активності додатка" "Відхилено" diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml index fc381a5fd..fbd8ab1e1 100644 --- a/res/values-ur/strings.xml +++ b/res/values-ur/strings.xml @@ -39,6 +39,7 @@ "صرف اسی وقت اجازت دیں جب ایپ استعمال میں ہو" "ایپس" "ایپ کی اجازتیں" + "اجازت کا مینیجر" "دوبارہ نہ پوچھیں" "کوئی اجازت نہیں ہے" "اضافی اجازتیں" @@ -51,7 +52,7 @@ "ایک نامعلوم کارروائی انجام دیں" "%2$d میں سے %1$d ایپس کو اجازت دے دی گئی" "حالیہ استعمال" - "تفصیلات ملاحظہ کریں" + "اجازتوں کا ڈیش بورڈ دیکھیں" "سسٹم دکھائیں" "سسٹم چھپائیں" "کوئی ایپ نہیں ہے" @@ -90,9 +91,23 @@ "موجودہ اجازتیں" "ایپ کی مرحلہ بندی ہو رہی ہے…" "نامعلوم" - "اجازتوں کا استعمال" - "آخری رسائی: %1$s\n%2$s رسائیاں" - "آخری رسائی: %1$s\n%2$s رسائیاں (%3$s پس منظر میں)" + "ڈیش بورڈ" + + آخری بار رسائی: %1$s\n%2$s رسائیاں + آخری بار رسائی: %1$s\n%2$s رسائی + + + آخری بار رسائی: %1$s\n%2$s رسائیاں (%3$s پس منظر میں) + آخری بار رسائی: %1$s\n%2$s رسائی (%3$s پس منظر میں) + + + آخری بار رسائی: %1$s\n%2$s رسائیوں کی\nمدت: %3$s + آخری بار رسائی: %1$s\n%2$s رسائی کی\nمدت: %3$s + + + آخری بار رسائی: %1$s\n%2$s رسائیوں کی (%3$s پس منظر میں)\nمدت:%3$s + آخری بار رسائی: %1$s\n%2$s رسائی (%3$s پس منظر میں)\nمدت: %3$s + "کوئی اجازت" "کسی بھی وقت" "آخری 7 دن" @@ -135,6 +150,7 @@ "%1$s نے آپ کے %2$s تک رسائی نہیں کی ہے۔" "تفصیلی اجازتوں کا استعمال دیکھیں" "آخری رسائی: %1$s" + "کبھی بھی رسائی حاصل نہیں کی" "اجازت ہے" "صرف استعمال کے دوران اجازت ہے" "مسترد ہو گئی" diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml index ddab18083..32cfa0e85 100644 --- a/res/values-uz/strings.xml +++ b/res/values-uz/strings.xml @@ -39,6 +39,7 @@ "Faqat ilova faolligida ruxsat berish" "Ilovalar" "Ilovalar uchun ruxsatlar" + "Ruxsatlar menejeri" "Boshqa so‘ralmasin" "Ruxsat talab qilinmaydi" "Qo‘shimcha ruxsatlar" @@ -51,7 +52,7 @@ "noma’lum amalni bajarish" "Ruxsat berilgan ilovalar: %1$d / %2$d" "Oxirgi statistika" - "Tafsilotlar" + "Ruxsatlar panelini ochish" "Tizimga oid jarayonlar" "Tizimga oid jarayonlarni berkitish" "Hech qanday ilova topilmadi" @@ -90,9 +91,23 @@ "Joriy ruxsatlar" "Kutib turing…" "Noaniq" - "Ruxsatlar foydalanish" - "Oxirgi marta ishlatilgan: %1$s\n%2$s marta" - "Oxirgi marta ishlatilgan: %1$s\n%2$s marta (fonda %3$s marta)" + "Shaxsiy kabinet" + + Oxirgi ishlatish: %1$s\n%2$s marta + Oxirgi ishlatish: %1$s\n%2$s marta + + + Oxirgi ishlatish: %1$s\n%2$s marta (fonda %3$s marta) + Oxirgi ishlatish: %1$s\n%2$s marta (fonda: %3$s marta) + + + Oxirgi ishlatish: %1$s\n%2$s marta \nDavomiyligi: %3$s + Oxirgi ishlatish: %1$s\n%2$s marta \nDavomiyligi: %3$s + + + Oxirgi ishlatish: %1$s\n%2$s marta (fonda: %3$s ta)\nDavomiyligi:%3$s + Oxirgi ishlatish: %1$s\n%2$s marta (fonda: %3$s ta)\nDavomiyligi: %3$s + "Har qanday ruxsat" "Har qanday vaqt" "Oxirgi 7 kun" @@ -135,6 +150,7 @@ "%1$s ilovasi uchun %2$s ruxsati berilmagan." "Ruxsatlardan foydalanish haqida batafsil axborotni ochish" "Oxirgi marta ishlatilgan: %1$s" + "Hech qachon ishlatilmagan" "Taqdim etilgan ruxsat" "Foydalanilayotganda ruxsat beriladi" "Taqdim etilmagan ruxsatlar" @@ -171,8 +187,8 @@ "Sozlamalar" "%s xizmati qurilmangizdan butunlay foydalana oladi" "%s ta maxsus xizmat qurilmangizdan butunlay foydalana oladi" - "%s ekraningiz, bajargan amallaringiz va yozuvlaringizni koʻra oladi hamda ekraningizni boshqa oladi" - "Bu xizmatlar ekraningiz, bajargan amallaringiz va yozuvlaringizni koʻra oladi hamda ekraningizni boshqara oladi" + "%s ekran, bajargan amallaringiz va kiritgan matnlaringizni koʻra oladi hamda ekraningizni boshqa oladi." + "Bu xizmatlar ekran, bajargan amallaringiz va kiritgan matnlaringizni koʻra oladi hamda ekraningizni boshqara oladi" "Birlamchi ilovalar" "Birlamchi ilovalar mavjud emas" "Ish uchun birlamchi" diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml index 4d56f77c0..6af8b3db1 100644 --- a/res/values-vi/strings.xml +++ b/res/values-vi/strings.xml @@ -39,6 +39,7 @@ "Chỉ cho phép khi đang sử dụng ứng dụng" "Ứng dụng" "Quyền ứng dụng" + "Người quản lý quyền" "Không hỏi lại" "Không có quyền" "Quyền bổ sung" @@ -51,7 +52,7 @@ "thực hiện hành động không xác định" "Đã cho phép %1$d/%2$d ứng dụng" "Mức sử dụng gần đây" - "Xem chi tiết" + "Xem trang tổng quan về quyền" "Hiển thị hệ thống" "Ẩn hệ thống" "Không có ứng dụng" @@ -90,9 +91,23 @@ "Các quyền hiện tại" "Đang thử nghiệm ứng dụng…" "Không xác định" - "Sử dụng quyền" - "Lần truy cập gần đây nhất: %1$s\n%2$s lần truy cập" - "Lần truy cập gần đây nhất: %1$s\n%2$s lần truy cập (%3$s dưới nền)" + "Trang tổng quan" + + Lần truy cập gần đây nhất: %1$s\n%2$s lần truy cập + Lần truy cập gần đây nhất: %1$s\n%2$s lần truy cập + + + Lần truy cập gần đây nhất: %1$s\n%2$s lần truy cập (%3$s trong nền) + Lần truy cập gần đây nhất: %1$s\n%2$s lần truy cập (%3$s trong nền) + + + Lần truy cập gần đây nhất: %1$s\n%2$s lần truy cập\nThời lượng: %3$s + Lần truy cập gần đây nhất: %1$s\n%2$s lần truy cập\nThời lượng: %3$s + + + Lần truy cập gần đây nhất: %1$s\n%2$s lần truy cập (%3$s trong nền)\nThời lượng: %3$s + Lần truy cập gần đây nhất: %1$s\n%2$s lần truy cập (%3$s trong nền)\nThời lượng: %3$s + "Mọi quyền" "Mọi lúc" "7 ngày qua" @@ -135,6 +150,7 @@ "%1$s chưa truy cập vào %2$s của bạn." "Xem mức sử dụng quyền chi tiết" "Lần truy cập gần đây nhất: %1$s" + "Chưa bao giờ truy cập" "Được phép" "Chỉ cho phép khi đang sử dụng" "Bị từ chối" diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml index e07e70421..795b57684 100644 --- a/res/values-zh-rCN/strings.xml +++ b/res/values-zh-rCN/strings.xml @@ -39,6 +39,7 @@ "仅在使用该应用期间允许" "应用" "应用权限" + "权限管理器" "不再询问" "没有权限" "其他权限" @@ -51,7 +52,7 @@ "执行未知操作" "已授权 %1$d 个应用(共 %2$d 个)" "最近的使用情况" - "查看详情" + "查看权限信息中心" "显示系统应用" "隐藏系统应用" "没有应用" @@ -90,9 +91,23 @@ "当前权限" "正在准备安装应用…" "未知" - "权限使用情况" - "上次访问时间:%1$s\n访问了 %2$s 次" - "上次访问时间:%1$s\n访问了 %2$s 次(其中有 %3$s 次为后台访问)" + "信息中心" + + 上次访问时间:%1$s\n访问次数:%2$s + 上次访问时间:%1$s\n访问次数:%2$s + + + 上次访问时间:%1$s\n访问次数:%2$s 次(其中有 %3$s 次是后台访问) + 上次访问时间:%1$s\n访问次数:%2$s 次(其中有 %3$s 次是后台访问) + + + 上次访问时间:%1$s\n访问次数:%2$s 次,\n时长:%3$s + 上次访问时间:%1$s\n访问次数:%2$s 次,\n时长:%3$s + + + 上次访问时间:%1$s\n访问次数:%2$s 次(其中有 %3$s 次是后台访问)\n时长:%3$s + 上次访问时间:%1$s\n访问次数:%2$s 次(其中有 %3$s 次是后台访问)\n时长:%3$s + "不限权限" "不限时间" "过去 7 天" @@ -135,6 +150,7 @@ "%1$s尚未取得您的%2$s访问权限。" "查看权限使用情况详情" "上次访问时间:%1$s" + "从未访问" "已允许" "仅在使用时允许" "已拒绝" @@ -168,16 +184,11 @@ "打开" "卸载" "强行停止" - - - - - - - - - - + "设置" + "%s对您的设备拥有完整访问权限" + "有 %s 项无障碍服务对您的设备拥有完整访问权限" + "%s不但可以查看您的屏幕、操作和输入内容,而且还能执行操作和控制显示内容。" + "这些服务不但可以查看您的屏幕、操作和输入内容,而且还能执行操作和控制显示内容。" "默认应用" "没有任何默认应用" "默认工作应用" @@ -199,11 +210,9 @@ "选接电话应用" "通话配套应用" "汽车投影应用" - - + "不支持工作资料" "注意:如果您重启设备并设置了屏幕锁定,则必须将设备解锁才能运行此应用。" - - + "Google 助理将可读取您系统中使用的应用的相关信息,其中包括您屏幕上显示的信息或应用中可使用的信息。" "分享调试数据" "是否分享详细调试数据?" "%1$s请求上传调试信息。" diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml index 44fe511cb..ccaa70b04 100644 --- a/res/values-zh-rHK/strings.xml +++ b/res/values-zh-rHK/strings.xml @@ -39,6 +39,7 @@ "只在使用應用程式時允許" "應用程式" "應用程式權限" + "權限管理員" "不要再詢問" "沒有權限" "其他權限" @@ -51,7 +52,7 @@ "執行不明的操作" "已允許 %1$d 個應用程式 (共 %2$d 個)" "近期使用情況" - "查看詳情" + "查看權限資訊主頁" "顯示系統" "隱藏系統" "沒有應用程式" @@ -90,9 +91,23 @@ "目前權限" "正在準備安裝應用程式…" "不明" - "權限使用情況" - "上次存取時間:%1$s\n%2$s 次存取" - "上次存取時間:%1$s\n%2$s 次存取 (%3$s 次在背景存取)" + "資訊主頁" + + 上次存取時間:%1$s\n%2$s 次存取 + 上次存取時間:%1$s\n%2$s 次存取 + + + 上次存取時間:%1$s\n%2$s 次存取 (%3$s 次在背景存取) + 上次存取時間:%1$s\n%2$s 次存取 (%3$s 次在背景存取) + + + 上次存取時間:%1$s\n%2$s 次存取\n時長:%3$s + 上次存取時間:%1$s\n%2$s 次存取\n時長:%3$s + + + 上次存取時間:%1$s\n%2$s 次存取 (%3$s 次在背景存取)\n時長:%3$s + 上次存取時間:%1$s\n%2$s 次存取 (%3$s 次在背景存取)\n時長:%3$s + "任何權限" "不限時間" "過去 7 天" @@ -135,6 +150,7 @@ "「%1$s」沒有存取%2$s。" "查看詳細的權限使用情況" "上次存取時間:%1$s" + "從未存取過" "已允許" "只在使用時允許" "已拒絕" @@ -168,16 +184,11 @@ "開啟" "解除安裝" "強制停止" - - - - - - - - - - + "設定" + "%s可以取得您裝置的完整存取權" + "%s 個無障礙服務可以取得您裝置的完整存取權" + "「%s」可以查看您的螢幕、操作和輸入內容、執行操作以及控制顯示屏。" + "這些服務可以查看您的螢幕、操作和輸入內容、執行操作以及控制顯示屏。" "預設應用程式" "沒有預設應用程式" "預設用於工作" @@ -199,11 +210,9 @@ "來電篩選應用程式" "通話隨附應用程式" "「汽車投影」應用程式" - - + "不支援工作設定檔" "請注意:如果您重新啟動裝置並設定了螢幕鎖定,就必須先將裝置解鎖,才可執行這個應用程式。" - - + "這個小幫手將能讀取系統目前使用的應用程式資料,包括螢幕顯示的資料或可在應用程式中存取的資料。" "分享偵錯資料" "要分享詳細的偵錯資料嗎?" "「%1$s」要求上載偵錯資料。" diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml index 85b6ececb..5e0d20eeb 100644 --- a/res/values-zh-rTW/strings.xml +++ b/res/values-zh-rTW/strings.xml @@ -39,6 +39,7 @@ "僅限應用程式使用期間" "應用程式" "應用程式權限" + "權限管理員" "不要再詢問" "沒有權限" "其他權限" @@ -51,7 +52,7 @@ "執行不明的動作" "已授權給 %1$d 個應用程式 (共 %2$d 個)" "最近的權限使用資料" - "查看詳細資料" + "查看權限資訊主頁" "顯示系統" "隱藏系統" "沒有應用程式" @@ -90,9 +91,23 @@ "目前權限" "正在準備應用程式安裝程序…" "不明" - "權限使用狀況" - "上次存取時間:%1$s\n存取次數:%2$s 次" - "上次存取時間:%1$s\n存取次數:%2$s 次 (有 %3$s 次在背景存取)" + "資訊主頁" + + 上次存取時間:%1$s\n存取次數:%2$s + 上次存取時間:%1$s\n存取次數:%2$s + + + 上次存取時間:%1$s\n存取次數:%2$s 次 (有 %3$s 次在背景存取) + 上次存取時間:%1$s\n存取次數:%2$s 次 (有 %3$s 次在背景存取) + + + 上次存取時間:%1$s\n存取次數:%2$s 次\n持續時間:%3$s + 上次存取時間:%1$s\n存取次數:%2$s 次\n持續時間:%3$s + + + 上次存取時間:%1$s\n存取次數:%2$s 次 (有 %3$s 次在背景存取)\n持續時間:%3$s + 上次存取時間:%1$s\n存取次數:%2$s 次 (有 %3$s 次在背景存取)\n持續時間:%3$s + "任意權限" "不限時間" "過去 7 天" @@ -135,6 +150,7 @@ "「%1$s」尚未取得你的%2$s存取權。" "查看詳細的權限使用情況" "上次存取時間:%1$s" + "從未存取" "已允許" "僅在使用時允許" "已拒絕" diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml index 448a81fc3..86de65961 100644 --- a/res/values-zu/strings.xml +++ b/res/values-zu/strings.xml @@ -39,6 +39,7 @@ "Vumela kuphela ngenkathi uhlelo lokusebenza lusebenza" "Izinhlelo zokusebenza" "Izimvume zohlelo lokusebenza" + "Isiphathi semvume" "Ungaphindi ubuze" "Akukho zimvume" "Izimvume ezingeziwe" @@ -51,7 +52,7 @@ "Yenza isenzo esingaziwa" "%1$d kuzinhlelo zokusebenza ezingu-%2$d ezivunyelwe" "Ukusebenzisa kwakamuva" - "Buka imininingwane" + "Buka izimvume zedeshibhodi" "Bonisa isistimu" "Fihla isistimu" "Azikho izinhlelo zokusebenza" @@ -90,9 +91,23 @@ "Izimvume zamanje" "Ifaka kusiteji uhlelo lokusebenza…" "Akwaziwa" - "Ukusetshenziswa kwezimvume" - "Ukufinyelela kokugcina: %1$s\n%2$s iyafinyelela" - "Ukufinyelela kokugcina: %1$s\n%2$s iyafinyelela (%3$s ngemuva)" + "Ideshibhodi" + + Ukufinyelela kokugcina: %1$s\n%2$s iyafinyelela + Ukufinyelela kokugcina: %1$s\n%2$s iyafinyelela + + + Ukufinyelela kokugcina: %1$s\n%2$s iyafinyelela (%3$s ngemuva) + Ukufinyelela kokugcina: %1$s\n%2$s iyafinyelela (%3$s ngemuva) + + + Ukufinyelela kokugcina: %1$s\n%2$s iyafinyelela\nUbude besikhathi: %3$s + Ukufinyelela kokugcina: %1$s\n%2$s iyafinyelela\nUbude besikhathi: %3$s + + + Ukufinyelela kokugcina: %1$s\n%2$s iyafinyelela (%3$s ngemuva)\nUbude besikhathi: %3$s + Ukufinyelela kokugcina: %1$s\n%2$s iyafinyelela (%3$s ngemuva)\nUbude besikhathi: %3$s + "Noma iyiphi imvume" "Noma yisiphi isikhathi" "Izinsuku zokugcina ezingu-7" @@ -135,6 +150,7 @@ "%1$s ayifinyelele i-%2$s yakho." "Buka ukusetshenziswa kwezimvume ezinemininingwane" "Kugcine ukufinyelelwa: %1$s" + "Akukaze kwafinyelelwa" "Kuvumelekile" "Kuvunyelwe kuphela ngenkathi kusetshenziswa" "Kunqatshiwe" -- GitLab From fa7cdc1142abec1c63b97551656df69ee7603ccc Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Mon, 4 Mar 2019 15:55:17 -0800 Subject: [PATCH 408/701] Link from accessibility usage dialog to individual service. Fixes: 123693167 Test: Click on individual icons and see their setting. Test: Click on "Settings" with only one service and see its setting. Change-Id: I47e58a4a0028209535644f2d848c67693faf2776 --- AndroidManifest.xml | 1 + .../ReviewAccessibilityServicesActivity.java | 36 ++++++++++++++----- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 9a329e3f6..dc351bf88 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -34,6 +34,7 @@ + diff --git a/src/com/android/packageinstaller/permission/ui/ReviewAccessibilityServicesActivity.java b/src/com/android/packageinstaller/permission/ui/ReviewAccessibilityServicesActivity.java index c2bb9bb9d..7be781b3b 100644 --- a/src/com/android/packageinstaller/permission/ui/ReviewAccessibilityServicesActivity.java +++ b/src/com/android/packageinstaller/permission/ui/ReviewAccessibilityServicesActivity.java @@ -19,9 +19,11 @@ package com.android.packageinstaller.permission.ui; import android.accessibilityservice.AccessibilityServiceInfo; import android.app.AlertDialog; import android.app.AppOpsManager; +import android.content.ComponentName; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.ResolveInfo; +import android.content.pm.ServiceInfo; import android.os.Bundle; import android.provider.Settings; import android.text.TextUtils; @@ -54,20 +56,26 @@ public final class ReviewAccessibilityServicesActivity extends FragmentActivity return; } + AccessibilityManager accessibilityManager = getSystemService( + AccessibilityManager.class); + List services = accessibilityManager + .getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_ALL_MASK); + new AlertDialog.Builder(this) - .setView(createDialogView()) + .setView(createDialogView(services)) .setPositiveButton(R.string.ok, null) - .setNeutralButton(R.string.settings, (dialog, which) -> - startActivity(new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS))) + .setNeutralButton(R.string.settings, (dialog, which) -> { + if (services.size() == 1) { + startAccessibilityScreen(services.get(0).getResolveInfo().serviceInfo); + } else { + startActivity(new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS)); + } + }) .setOnDismissListener((dialog) -> finish()) .show(); } - private @NonNull View createDialogView() { - AccessibilityManager accessibilityManager = getSystemService( - AccessibilityManager.class); - List services = accessibilityManager - .getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_ALL_MASK); + private @NonNull View createDialogView(List services) { AppOpsManager appOpsManager = getSystemService(AppOpsManager.class); LayoutInflater layoutInflater = LayoutInflater.from(this); @@ -76,7 +84,8 @@ public final class ReviewAccessibilityServicesActivity extends FragmentActivity int numServices = services.size(); for (int i = 0; i < numServices; i++) { ResolveInfo resolveInfo = services.get(i).getResolveInfo(); - ApplicationInfo appInfo = resolveInfo.serviceInfo.applicationInfo; + ServiceInfo serviceInfo = resolveInfo.serviceInfo; + ApplicationInfo appInfo = serviceInfo.applicationInfo; CharSequence label = getLabel(resolveInfo); long lastAccessTime = getLastAccessTime(appInfo, appOpsManager); @@ -123,6 +132,8 @@ public final class ReviewAccessibilityServicesActivity extends FragmentActivity Utils.getAbsoluteTimeString(this, lastAccessTime))); } + itemView.setOnClickListener((v) -> startAccessibilityScreen(serviceInfo)); + servicesListView.addView(itemView); } } @@ -130,6 +141,13 @@ public final class ReviewAccessibilityServicesActivity extends FragmentActivity return view; } + private void startAccessibilityScreen(ServiceInfo serviceInfo) { + Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_DETAILS_SETTINGS); + intent.putExtra(Intent.EXTRA_COMPONENT_NAME, + new ComponentName(serviceInfo.packageName, serviceInfo.name).flattenToString()); + startActivity(intent); + } + private @NonNull CharSequence getLabel(@NonNull ResolveInfo resolveInfo) { return BidiFormatter.getInstance().unicodeWrap( TextUtils.makeSafeForPresentation( -- GitLab From 37e87956395a159322bc950e72a25f7f6f114290 Mon Sep 17 00:00:00 2001 From: Eugene Susla Date: Tue, 19 Feb 2019 11:16:38 -0800 Subject: [PATCH 409/701] Introduce and populate PackageManager.FLAG_PERMISSION_USER_VISIBLE Bug: 124317989 Test: adb shell dumpsys package com.google.android.apps.messaging and ensure permissions without flag GRANTED_BY_DEFAULT have flag USER_VISIBLE Change-Id: Id6097a592399ecdc3f134ed1b009ca5e4c281157 --- .../permission/model/Permission.java | 8 +++ .../permission/utils/Utils.java | 9 +++ .../service/RoleControllerServiceImpl.java | 56 +++++++++++++++++++ 3 files changed, 73 insertions(+) diff --git a/src/com/android/packageinstaller/permission/model/Permission.java b/src/com/android/packageinstaller/permission/model/Permission.java index 617a00833..3a7f62ee1 100644 --- a/src/com/android/packageinstaller/permission/model/Permission.java +++ b/src/com/android/packageinstaller/permission/model/Permission.java @@ -174,6 +174,14 @@ public final class Permission { return (mFlags & PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0; } + public boolean isUserSensitiveWhenGranted() { + return (mFlags & PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED) != 0; + } + + public boolean isUserSensitiveWhenDenied() { + return (mFlags & PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED) != 0; + } + /** * If this permission is split into a foreground and background permission, this is the name * of the background permission. diff --git a/src/com/android/packageinstaller/permission/utils/Utils.java b/src/com/android/packageinstaller/permission/utils/Utils.java index 307255f8b..9905086dd 100644 --- a/src/com/android/packageinstaller/permission/utils/Utils.java +++ b/src/com/android/packageinstaller/permission/utils/Utils.java @@ -405,6 +405,15 @@ public final class Utils { return new ArrayList<>(PLATFORM_PERMISSION_GROUPS.keySet()); } + /** + * Get the names of the platform permissions. + * + * @return the names of the platform permissions. + */ + public static List getPlatformPermissions() { + return new ArrayList<>(PLATFORM_PERMISSIONS.keySet()); + } + /** * Should UI show this permission. * diff --git a/src/com/android/packageinstaller/role/service/RoleControllerServiceImpl.java b/src/com/android/packageinstaller/role/service/RoleControllerServiceImpl.java index 0b42a7418..032c9be69 100644 --- a/src/com/android/packageinstaller/role/service/RoleControllerServiceImpl.java +++ b/src/com/android/packageinstaller/role/service/RoleControllerServiceImpl.java @@ -27,6 +27,7 @@ import android.os.Build; import android.os.Handler; import android.os.HandlerThread; import android.os.Process; +import android.os.SystemClock; import android.os.UserHandle; import android.rolecontrollerservice.RoleControllerService; import android.text.TextUtils; @@ -336,6 +337,61 @@ public class RoleControllerServiceImpl extends RoleControllerService { if (callback != null) { callback.onSuccess(); } + + // Populate PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED + PackageManager pm = getPackageManager(); + UserHandle user = Process.myUserHandle(); + List pkgs = pm.getInstalledPackages(0); + List platformPerms = Utils.getPlatformPermissions(); + ArraySet pkgsWithLauncherIcon = Utils.getLauncherPackages(this); + List iterationTimesNs = new ArrayList<>(); + + long startMs = SystemClock.uptimeMillis(); + for (int i = 0, size = pkgs.size(); i < size; i++) { + PackageInfo pkg = pkgs.get(i); + boolean pkgHasLauncherIcon = pkgsWithLauncherIcon.contains(pkg.packageName); + boolean pkgIsSystemApp = (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; + + for (int j = 0, permSize = platformPerms.size(); j < permSize; j++) { + String perm = platformPerms.get(j); + + long iterationStart = DEBUG ? SystemClock.elapsedRealtimeNanos() : 0L; + + int flags; + if (pkgIsSystemApp && !pkgHasLauncherIcon) { + boolean permGranted = pm.checkPermission(perm, pkg.packageName) + == PackageManager.PERMISSION_GRANTED; + boolean permGrantedByDefault = permGranted + && (pm.getPermissionFlags(perm, pkg.packageName, user) + & PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0; + if (permGrantedByDefault) { + flags = 0; + } else { + flags = PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED; + } + } else { + flags = PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED + | PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED; + } + //TODO(b/124317989): flags |= userOverrideInUi + pm.updatePermissionFlags(perm, pkg.packageName, + PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED + | PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED, flags, + user); + + if (DEBUG) { + iterationTimesNs.add(SystemClock.elapsedRealtimeNanos() - iterationStart); + } + } + } + if (DEBUG) { + long avgIter = iterationTimesNs.stream().reduce(0L, (a, b) -> a + b) + / iterationTimesNs.size(); + Log.i(LOG_TAG, "Populating FLAG_PERMISSION_USER_SENSITIVE_* for " + + pkgs.size() + "pkgs & " + + platformPerms.size() + "perms took " + (SystemClock.uptimeMillis() - startMs) + + "ms, avg iteration took " + avgIter + "ns"); + } } @WorkerThread -- GitLab From 161ce4bff1999469b1e869aa6c6f0b3ffe9d1354 Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Sat, 2 Mar 2019 13:57:14 -0800 Subject: [PATCH 410/701] Update the policy to match the consensus Test: Looked at dumpsys output which flags were granted Change-Id: I6fea59b74930fa6cc007a831d30a8601a5dfca4f --- .../permission/utils/Utils.java | 5 +- .../service/RoleControllerServiceImpl.java | 54 +++++++++---------- 2 files changed, 27 insertions(+), 32 deletions(-) diff --git a/src/com/android/packageinstaller/permission/utils/Utils.java b/src/com/android/packageinstaller/permission/utils/Utils.java index 9905086dd..e3d51a61f 100644 --- a/src/com/android/packageinstaller/permission/utils/Utils.java +++ b/src/com/android/packageinstaller/permission/utils/Utils.java @@ -78,6 +78,7 @@ import java.util.Calendar; import java.util.Collections; import java.util.List; import java.util.Locale; +import java.util.Set; public final class Utils { @@ -410,8 +411,8 @@ public final class Utils { * * @return the names of the platform permissions. */ - public static List getPlatformPermissions() { - return new ArrayList<>(PLATFORM_PERMISSIONS.keySet()); + public static Set getPlatformPermissions() { + return PLATFORM_PERMISSIONS.keySet(); } /** diff --git a/src/com/android/packageinstaller/role/service/RoleControllerServiceImpl.java b/src/com/android/packageinstaller/role/service/RoleControllerServiceImpl.java index 032c9be69..a4da2228a 100644 --- a/src/com/android/packageinstaller/role/service/RoleControllerServiceImpl.java +++ b/src/com/android/packageinstaller/role/service/RoleControllerServiceImpl.java @@ -27,7 +27,6 @@ import android.os.Build; import android.os.Handler; import android.os.HandlerThread; import android.os.Process; -import android.os.SystemClock; import android.os.UserHandle; import android.rolecontrollerservice.RoleControllerService; import android.text.TextUtils; @@ -39,6 +38,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.WorkerThread; +import com.android.packageinstaller.permission.utils.ArrayUtils; import com.android.packageinstaller.permission.utils.CollectionUtils; import com.android.packageinstaller.permission.utils.Utils; import com.android.packageinstaller.role.model.Role; @@ -48,6 +48,7 @@ import com.android.packageinstaller.role.utils.PackageUtils; import java.util.ArrayList; import java.util.List; import java.util.Objects; +import java.util.Set; /** * Implementation of {@link RoleControllerService}. @@ -334,36 +335,41 @@ public class RoleControllerServiceImpl extends RoleControllerService { } } + updateUserSensitive(); + if (callback != null) { callback.onSuccess(); } + } - // Populate PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED + /** + * Update the {@link PackageManager#FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED} and + * {@link PackageManager#FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED} for all apps of this user. + */ + private void updateUserSensitive() { PackageManager pm = getPackageManager(); UserHandle user = Process.myUserHandle(); - List pkgs = pm.getInstalledPackages(0); - List platformPerms = Utils.getPlatformPermissions(); + List pkgs = pm.getInstalledPackages(PackageManager.GET_PERMISSIONS); + Set platformPerms = Utils.getPlatformPermissions(); ArraySet pkgsWithLauncherIcon = Utils.getLauncherPackages(this); - List iterationTimesNs = new ArrayList<>(); - long startMs = SystemClock.uptimeMillis(); - for (int i = 0, size = pkgs.size(); i < size; i++) { - PackageInfo pkg = pkgs.get(i); + int numPkgs = pkgs.size(); + for (int pkgNum = 0; pkgNum < numPkgs; pkgNum++) { + PackageInfo pkg = pkgs.get(pkgNum); boolean pkgHasLauncherIcon = pkgsWithLauncherIcon.contains(pkg.packageName); boolean pkgIsSystemApp = (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; - for (int j = 0, permSize = platformPerms.size(); j < permSize; j++) { - String perm = platformPerms.get(j); - - long iterationStart = DEBUG ? SystemClock.elapsedRealtimeNanos() : 0L; + for (String perm : platformPerms) { + if (pkg.requestedPermissions == null || !ArrayUtils.contains( + pkg.requestedPermissions, perm)) { + continue; + } int flags; if (pkgIsSystemApp && !pkgHasLauncherIcon) { - boolean permGranted = pm.checkPermission(perm, pkg.packageName) - == PackageManager.PERMISSION_GRANTED; - boolean permGrantedByDefault = permGranted - && (pm.getPermissionFlags(perm, pkg.packageName, user) - & PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0; + boolean permGrantedByDefault = (pm.getPermissionFlags(perm, pkg.packageName, + user) & PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0; + if (permGrantedByDefault) { flags = 0; } else { @@ -373,25 +379,13 @@ public class RoleControllerServiceImpl extends RoleControllerService { flags = PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED | PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED; } - //TODO(b/124317989): flags |= userOverrideInUi + pm.updatePermissionFlags(perm, pkg.packageName, PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED | PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED, flags, user); - - if (DEBUG) { - iterationTimesNs.add(SystemClock.elapsedRealtimeNanos() - iterationStart); - } } } - if (DEBUG) { - long avgIter = iterationTimesNs.stream().reduce(0L, (a, b) -> a + b) - / iterationTimesNs.size(); - Log.i(LOG_TAG, "Populating FLAG_PERMISSION_USER_SENSITIVE_* for " - + pkgs.size() + "pkgs & " - + platformPerms.size() + "perms took " + (SystemClock.uptimeMillis() - startMs) - + "ms, avg iteration took " + avgIter + "ns"); - } } @WorkerThread -- GitLab From a3029367d4f9a143a8048a5905217ebcff2d7493 Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Sat, 2 Mar 2019 14:42:42 -0800 Subject: [PATCH 411/701] Make permissions settings UI respect user sensitive. Test: Looked at UIs and saw flag honored Change-Id: Id349c7498ff4e6036edd00418b2aa6754c85a2fb --- .../permission/model/AppPermissionGroup.java | 16 +++++++++++++ .../permission/model/Permission.java | 20 +++++++++++----- .../permission/model/PermissionApps.java | 9 ++++--- .../permission/model/PermissionGroups.java | 9 ++++--- .../PermissionControllerServiceImpl.java | 22 +++++++---------- .../ManageStandardPermissionsFragment.java | 9 +++---- .../ui/handheld/PermissionAppsFragment.java | 6 +---- .../ui/handheld/PermissionUsageFragment.java | 5 ++-- .../television/ManagePermissionsFragment.java | 13 ++++------ .../ui/television/PermissionAppsFragment.java | 4 +--- .../permission/utils/Utils.java | 24 ++++++++----------- 11 files changed, 68 insertions(+), 69 deletions(-) diff --git a/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java b/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java index b6a447c78..1f2d110f5 100644 --- a/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java +++ b/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java @@ -428,6 +428,22 @@ public final class AppPermissionGroup implements Comparable return false; } + /** + * Are any of the permissions in this group user sensitive. + * + * @return {@code true} if any of the permissions in the group is user sensitive. + */ + public boolean isUserSensitive() { + final int permissionCount = mPermissions.size(); + for (int i = 0; i < permissionCount; i++) { + Permission permission = mPermissions.valueAt(i); + if (permission.isUserSensitive()) { + return true; + } + } + return false; + } + public void unsetReviewRequired() { final int permissionCount = mPermissions.size(); for (int i = 0; i < permissionCount; i++) { diff --git a/src/com/android/packageinstaller/permission/model/Permission.java b/src/com/android/packageinstaller/permission/model/Permission.java index 3a7f62ee1..b83465136 100644 --- a/src/com/android/packageinstaller/permission/model/Permission.java +++ b/src/com/android/packageinstaller/permission/model/Permission.java @@ -174,12 +174,20 @@ public final class Permission { return (mFlags & PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0; } - public boolean isUserSensitiveWhenGranted() { - return (mFlags & PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED) != 0; - } - - public boolean isUserSensitiveWhenDenied() { - return (mFlags & PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED) != 0; + /** + * Is the permission user sensitive, i.e. should it always be shown to the user. + * + *

Non-sensitive permission are usually hidden behind a setting in an overflow menu or + * some other kind of flag. + * + * @return {@code true} if the permission is user sensitive. + */ + public boolean isUserSensitive() { + if (isGrantedIncludingAppOp()) { + return (mFlags & PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED) != 0; + } else { + return (mFlags & PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED) != 0; + } } /** diff --git a/src/com/android/packageinstaller/permission/model/PermissionApps.java b/src/com/android/packageinstaller/permission/model/PermissionApps.java index 5d94045ee..4f92bb7c4 100644 --- a/src/com/android/packageinstaller/permission/model/PermissionApps.java +++ b/src/com/android/packageinstaller/permission/model/PermissionApps.java @@ -27,7 +27,6 @@ import android.os.AsyncTask; import android.os.UserHandle; import android.os.UserManager; import android.util.ArrayMap; -import android.util.ArraySet; import android.util.Log; import android.util.Pair; import android.util.SparseArray; @@ -114,13 +113,13 @@ public class PermissionApps { createMap(loadPermissionApps()); } - public int getGrantedCount(ArraySet launcherPkgs) { + public int getGrantedCount() { int count = 0; for (PermissionApp app : mPermApps) { if (!Utils.shouldShowPermission(mContext, app.getPermissionGroup())) { continue; } - if (Utils.isSystem(app, launcherPkgs)) { + if (!Utils.isGroupOrBgGroupUserSensitive(app.mAppPermissionGroup)) { // We default to not showing system apps, so hide them from count. continue; } @@ -131,13 +130,13 @@ public class PermissionApps { return count; } - public int getTotalCount(ArraySet launcherPkgs) { + public int getTotalCount() { int count = 0; for (PermissionApp app : mPermApps) { if (!Utils.shouldShowPermission(mContext, app.getPermissionGroup())) { continue; } - if (Utils.isSystem(app, launcherPkgs)) { + if (!Utils.isGroupOrBgGroupUserSensitive(app.mAppPermissionGroup)) { // We default to not showing system apps, so hide them from count. continue; } diff --git a/src/com/android/packageinstaller/permission/model/PermissionGroups.java b/src/com/android/packageinstaller/permission/model/PermissionGroups.java index 7c3f3a91e..26d68a416 100644 --- a/src/com/android/packageinstaller/permission/model/PermissionGroups.java +++ b/src/com/android/packageinstaller/permission/model/PermissionGroups.java @@ -165,7 +165,6 @@ public final class PermissionGroups implements LoaderCallbacks isCanceled, boolean getAppUiInfo, boolean getNonPlatformPermissions, @Nullable String groupName, @Nullable String packageName) { - ArraySet launcherPkgs = Utils.getLauncherPackages(context); PermissionApps.PmCache pmCache = new PermissionApps.PmCache( context.getPackageManager()); PermissionApps.AppDataCache appDataCache = new PermissionApps.AppDataCache( @@ -222,8 +221,8 @@ public final class PermissionGroups implements LoaderCallbacks pkgs = getPackageManager().getInstalledPackages(GET_PERMISSIONS); - ArraySet launcherPkgs = getLauncherPackages(this); int numApps = 0; @@ -404,10 +400,6 @@ public final class PermissionControllerServiceImpl extends PermissionControllerS for (int pkgNum = 0; pkgNum < numPkgs; pkgNum++) { PackageInfo pkg = pkgs.get(pkgNum); - if (!countSystem && isSystem(pkg.applicationInfo, launcherPkgs)) { - continue; - } - int numPerms = permissionNames.size(); for (int permNum = 0; permNum < numPerms; permNum++) { String perm = permissionNames.get(permNum); @@ -424,11 +416,15 @@ public final class PermissionControllerServiceImpl extends PermissionControllerS } else { AppPermissionGroup bgGroup = group.getBackgroundPermissions(); if (bgGroup != null && bgGroup.hasPermission(perm)) { - subGroup = group; + subGroup = bgGroup; } } if (subGroup != null) { + if (!countSystem && !subGroup.isUserSensitive()) { + continue; + } + if (!countOnlyGranted || subGroup.areRuntimePermissionsGranted()) { // The permission might not be granted, but some permissions of the group // are granted. In this case the permission is granted silently when the app @@ -446,8 +442,6 @@ public final class PermissionControllerServiceImpl extends PermissionControllerS @Override public @NonNull List onGetPermissionUsages( boolean countSystem, long numMillis) { - ArraySet launcherPkgs = getLauncherPackages(this); - ArrayMap groupUsers = new ArrayMap<>(); long curTime = System.currentTimeMillis(); @@ -465,9 +459,6 @@ public final class PermissionControllerServiceImpl extends PermissionControllerS if (appPermissionUsage.getAccessCount() <= 0) { continue; } - if (!countSystem && isSystem(appPermissionUsage.getApp(), launcherPkgs)) { - continue; - } List appGroups = appPermissionUsage.getGroupUsages(); int numGroups = appGroups.size(); @@ -480,6 +471,9 @@ public final class PermissionControllerServiceImpl extends PermissionControllerS if (!shouldShowPermission(this, groupUsage.getGroup())) { continue; } + if (!countSystem && !Utils.isGroupOrBgGroupUserSensitive(groupUsage.getGroup())) { + continue; + } CharSequence groupLabel = groupUsage.getGroup().getName(); Integer numUsers = groupUsers.get(groupLabel); diff --git a/src/com/android/packageinstaller/permission/ui/handheld/ManageStandardPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/ManageStandardPermissionsFragment.java index f2ba07a85..60ce7bc2c 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/ManageStandardPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/ManageStandardPermissionsFragment.java @@ -20,7 +20,6 @@ import static java.util.concurrent.TimeUnit.DAYS; import android.content.Context; import android.content.Intent; import android.os.Bundle; -import android.util.ArraySet; import android.util.Pair; import android.view.LayoutInflater; import android.view.MenuItem; @@ -57,7 +56,6 @@ public final class ManageStandardPermissionsFragment extends ManagePermissionsFr private @NonNull PermissionUsages mPermissionUsages; private @NonNull AppEntitiesHeaderController mAppUsageController; - private @NonNull ArraySet mLauncherPkgs; /** * @return A new fragment @@ -72,7 +70,6 @@ public final class ManageStandardPermissionsFragment extends ManagePermissionsFr super.onCreate(icicle); mPermissionUsages = new PermissionUsages(getContext()); - mLauncherPkgs = Utils.getLauncherPackages(getContext()); } @Override @@ -185,9 +182,6 @@ public final class ManageStandardPermissionsFragment extends ManagePermissionsFr if (appPermissionUsage.getAccessCount() <= 0) { continue; } - if (Utils.isSystem(appPermissionUsage.getApp(), mLauncherPkgs)) { - continue; - } // Get the msot recent usage by this app. GroupUsage mostRecentUsage = null; @@ -203,6 +197,9 @@ public final class ManageStandardPermissionsFragment extends ManagePermissionsFr if (groupUsage.getGroup().getLabel().equals("Storage")) { continue; } + if (!Utils.isGroupOrBgGroupUserSensitive(groupUsage.getGroup())) { + continue; + } if (mostRecentUsage == null || groupUsage.getLastAccessTime() >= mostRecentUsage.getLastAccessTime()) { diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java index 426c74d6f..eba5395bc 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java @@ -21,7 +21,6 @@ import android.content.Intent; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.util.ArrayMap; -import android.util.ArraySet; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; @@ -74,8 +73,6 @@ public final class PermissionAppsFragment extends PermissionsFrameFragment imple private PreferenceScreen mExtraScreen; - private ArraySet mLauncherPkgs; - private boolean mShowSystem; private boolean mHasSystemApps; private MenuItem mShowSystemMenu; @@ -99,7 +96,6 @@ public final class PermissionAppsFragment extends PermissionsFrameFragment imple if (ab != null) { ab.setDisplayHomeAsUpEnabled(true); } - mLauncherPkgs = Utils.getLauncherPackages(getContext()); String groupName = getArguments().getString(Intent.EXTRA_PERMISSION_NAME); mPermissionApps = new PermissionApps(getActivity(), groupName, this); @@ -252,7 +248,7 @@ public final class PermissionAppsFragment extends PermissionsFrameFragment imple existingPref.setOrder(Preference.DEFAULT_ORDER); } - boolean isSystemApp = Utils.isSystem(app, mLauncherPkgs); + boolean isSystemApp = !Utils.isGroupOrBgGroupUserSensitive(group); if (isSystemApp && !menuOptionsInvalided) { mHasSystemApps = true; diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java index 5b3e2fd0f..4ac14d42d 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java @@ -114,7 +114,6 @@ public class PermissionUsageFragment extends SettingsWithButtonHeader implements private @NonNull PermissionUsages mPermissionUsages; private Collator mCollator; - private ArraySet mLauncherPkgs; private String mFilterGroup; @@ -200,7 +199,6 @@ public class PermissionUsageFragment extends SettingsWithButtonHeader implements mFilterGroup = null; mCollator = Collator.getInstance( context.getResources().getConfiguration().getLocales().get(0)); - mLauncherPkgs = Utils.getLauncherPackages(context); mPermissionUsages = new PermissionUsages(context); } @@ -400,7 +398,8 @@ public class PermissionUsageFragment extends SettingsWithButtonHeader implements || groupUsage.getLastAccessTime() < startTime) { continue; } - final boolean isSystemApp = Utils.isSystem(appUsage.getApp(), mLauncherPkgs); + final boolean isSystemApp = !Utils.isGroupOrBgGroupUserSensitive( + groupUsage.getGroup()); if (!mHasSystemApps) { if (isSystemApp) { mHasSystemApps = true; diff --git a/src/com/android/packageinstaller/permission/ui/television/ManagePermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/television/ManagePermissionsFragment.java index d8a975b16..43d2d9720 100644 --- a/src/com/android/packageinstaller/permission/ui/television/ManagePermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/television/ManagePermissionsFragment.java @@ -21,20 +21,20 @@ import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; import android.os.Bundle; +import android.util.Log; +import android.view.MenuItem; +import android.view.View; + import androidx.annotation.Nullable; import androidx.preference.Preference; import androidx.preference.Preference.OnPreferenceClickListener; import androidx.preference.PreferenceScreen; -import android.util.ArraySet; -import android.util.Log; -import android.view.MenuItem; -import android.view.View; -import com.android.permissioncontroller.R; import com.android.packageinstaller.permission.model.PermissionApps.PmCache; import com.android.packageinstaller.permission.model.PermissionGroup; import com.android.packageinstaller.permission.model.PermissionGroups; import com.android.packageinstaller.permission.utils.Utils; +import com.android.permissioncontroller.R; import java.util.List; @@ -46,8 +46,6 @@ public final class ManagePermissionsFragment extends SettingsWithHeader private static final String EXTRA_PREFS_KEY = "extra_prefs_key"; - private ArraySet mLauncherPkgs; - private PermissionGroups mPermissions; private PreferenceScreen mExtraScreen; @@ -65,7 +63,6 @@ public final class ManagePermissionsFragment extends SettingsWithHeader if (ab != null) { ab.setDisplayHomeAsUpEnabled(true); } - mLauncherPkgs = Utils.getLauncherPackages(getContext()); mPermissions = new PermissionGroups(getContext(), getLoaderManager(), this, false, true); } diff --git a/src/com/android/packageinstaller/permission/ui/television/PermissionAppsFragment.java b/src/com/android/packageinstaller/permission/ui/television/PermissionAppsFragment.java index c6705544d..6cbbbb2ef 100644 --- a/src/com/android/packageinstaller/permission/ui/television/PermissionAppsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/television/PermissionAppsFragment.java @@ -71,7 +71,6 @@ public final class PermissionAppsFragment extends SettingsWithHeader implements private PreferenceScreen mExtraScreen; private ArraySet mToggledGroups; - private ArraySet mLauncherPkgs; private boolean mHasConfirmedRevoke; private boolean mShowSystem; @@ -85,7 +84,6 @@ public final class PermissionAppsFragment extends SettingsWithHeader implements public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setLoading(true /* loading */, false /* animate */); - mLauncherPkgs = Utils.getLauncherPackages(getContext()); String groupName = getArguments().getString(Intent.EXTRA_PERMISSION_NAME); mPermissionApps = new PermissionApps(getActivity(), groupName, this); } @@ -196,7 +194,7 @@ public final class PermissionAppsFragment extends SettingsWithHeader implements existingPref = mExtraScreen.findPreference(key); } - boolean isSystemApp = Utils.isSystem(app, mLauncherPkgs); + boolean isSystemApp = !Utils.isGroupOrBgGroupUserSensitive(app.getPermissionGroup()); if (isSystemApp && !menuOptionsInvalided) { mHasSystemApps = true; diff --git a/src/com/android/packageinstaller/permission/utils/Utils.java b/src/com/android/packageinstaller/permission/utils/Utils.java index e3d51a61f..f2202a94f 100644 --- a/src/com/android/packageinstaller/permission/utils/Utils.java +++ b/src/com/android/packageinstaller/permission/utils/Utils.java @@ -69,8 +69,6 @@ import androidx.core.util.Preconditions; import com.android.launcher3.icons.IconFactory; import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.model.AppPermissionUsage; -import com.android.packageinstaller.permission.model.AppPermissions; -import com.android.packageinstaller.permission.model.PermissionApps.PermissionApp; import com.android.permissioncontroller.R; import java.util.ArrayList; @@ -465,18 +463,16 @@ public final class Utils { return context.getPackageManager().getInstalledApplications(0); } - public static boolean isSystem(PermissionApp app, ArraySet launcherPkgs) { - return isSystem(app.getAppInfo(), launcherPkgs); - } - - public static boolean isSystem(AppPermissions app, ArraySet launcherPkgs) { - return isSystem(app.getPackageInfo().applicationInfo, launcherPkgs); - } - - public static boolean isSystem(ApplicationInfo info, ArraySet launcherPkgs) { - return ((info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) - && (info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) == 0 - && !launcherPkgs.contains(info.packageName); + /** + * Is the group or background group user sensitive? + * + * @param group The group that might be user sensitive + * + * @return {@code true} if the group (or it's subgroup) is user sensitive. + */ + public static boolean isGroupOrBgGroupUserSensitive(AppPermissionGroup group) { + return group.isUserSensitive() || (group.getBackgroundPermissions() != null + && group.getBackgroundPermissions().isUserSensitive()); } public static boolean areGroupPermissionsIndividuallyControlled(Context context, String group) { -- GitLab From c7c123a87e6772f1a81f7b81c8d971d93f20456c Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Fri, 1 Mar 2019 17:53:57 -0800 Subject: [PATCH 412/701] Guard ReviewAccessibilityServicesActivity with the new permission. Fixes: 126944474 Test: Load activity. Change-Id: I36fe38b2a21af7e046ea275414343537af41b3e2 --- AndroidManifest.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 9a329e3f6..af6bd08ec 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -140,7 +140,8 @@ + android:theme="@android:style/Theme.DeviceDefault.Light.Dialog.NoActionBar" + android:permission="android.permission.REVIEW_ACCESSIBILITY_SERVICES" > -- GitLab From 15a4fd56e6e991f2ae7cbb8d79a21f1abc2748d6 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Mon, 4 Mar 2019 13:25:30 -0800 Subject: [PATCH 413/701] Ensure permission icons are the same size. Some icons were smaller than the maximum size, so make them scale up to the maximum size. Bug: 122987805 Test: Icons look the same size. Change-Id: I4666a05799d7f92a1aec04649a332e6168de32ad --- .../ui/handheld/ManagePermissionsFragment.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/com/android/packageinstaller/permission/ui/handheld/ManagePermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/ManagePermissionsFragment.java index 0bba6cdfb..d41df26ad 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/ManagePermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/ManagePermissionsFragment.java @@ -171,10 +171,14 @@ abstract class ManagePermissionsFragment extends PermissionsFrameFragment public void onBindViewHolder(PreferenceViewHolder holder) { super.onBindViewHolder(holder); ImageView icon = ((ImageView) holder.findViewById(android.R.id.icon)); - icon.setMaxWidth(getContext().getResources().getDimensionPixelSize( - R.dimen.secondary_app_icon_size)); - icon.setMaxHeight(getContext().getResources().getDimensionPixelSize( - R.dimen.secondary_app_icon_size)); + icon.setAdjustViewBounds(true); + int size = getContext().getResources().getDimensionPixelSize( + R.dimen.secondary_app_icon_size); + icon.setMaxWidth(size); + icon.setMaxHeight(size); + icon.getLayoutParams().width = size; + icon.getLayoutParams().height = size; + icon.setScaleType(ImageView.ScaleType.FIT_CENTER); } } } -- GitLab From 562a2842294d6842bd08ab1d5448e83fcd019765 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Tue, 5 Mar 2019 09:46:13 -0800 Subject: [PATCH 414/701] Allow Talkback to speak the permission name. Fixes: 127237805 Test: Enable Talkback, click on access. Change-Id: Id380d3fe62daef7f4fb649c25feeaf1b4dc9a739 --- .../ui/handheld/ExpandablePreferenceGroup.java | 14 ++++++++++---- .../ui/handheld/PermissionUsageFragment.java | 5 +++-- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/com/android/packageinstaller/permission/ui/handheld/ExpandablePreferenceGroup.java b/src/com/android/packageinstaller/permission/ui/handheld/ExpandablePreferenceGroup.java index 79b6900a7..3e5bf793b 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/ExpandablePreferenceGroup.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/ExpandablePreferenceGroup.java @@ -17,6 +17,7 @@ package com.android.packageinstaller.permission.ui.handheld; import android.content.Context; +import android.util.Pair; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -24,6 +25,7 @@ import android.widget.ImageView; import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.preference.Preference; import androidx.preference.PreferenceGroup; import androidx.preference.PreferenceViewHolder; @@ -39,7 +41,7 @@ import java.util.List; public class ExpandablePreferenceGroup extends PreferenceGroup { private @NonNull Context mContext; private @NonNull List mPreferences; - private @NonNull List mSummaryIcons; + private @NonNull List> mSummaryIcons; private boolean mExpanded; public ExpandablePreferenceGroup(@NonNull Context context) { @@ -100,7 +102,11 @@ public class ExpandablePreferenceGroup extends PreferenceGroup { ViewGroup group = (ViewGroup) inflater.inflate(R.layout.title_summary_image_view, null); ImageView imageView = group.requireViewById(R.id.icon); - imageView.setImageResource(mSummaryIcons.get(i)); + Pair summaryIcons = mSummaryIcons.get(i); + imageView.setImageResource(summaryIcons.first); + if (summaryIcons.second != null) { + imageView.setContentDescription(summaryIcons.second); + } summaryFrame.addView(group); } } @@ -117,7 +123,7 @@ public class ExpandablePreferenceGroup extends PreferenceGroup { * * @param resId the resourceId of the drawable to use as the icon. */ - public void addSummaryIcon(@DrawableRes int resId) { - mSummaryIcons.add(resId); + public void addSummaryIcon(@DrawableRes int resId, @Nullable CharSequence contentDescription) { + mSummaryIcons.add(Pair.create(resId, contentDescription)); } } diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java index 5b3e2fd0f..162af32a4 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java @@ -492,7 +492,8 @@ public class PermissionUsageFragment extends SettingsWithButtonHeader implements parent.addPreference(createPermissionUsagePreference(context, appPermissionUsage, groupUsage, accessTimeString)); - parent.addSummaryIcon(groupUsage.getGroup().getIconResId()); + parent.addSummaryIcon(groupUsage.getGroup().getIconResId(), + groupUsage.getGroup().getLabel()); } setLoading(false, true); @@ -591,7 +592,7 @@ public class PermissionUsageFragment extends SettingsWithButtonHeader implements Utils.applyTint(context, icon, android.R.attr.colorControlNormal), // The cast should not be a prob in practice groupToAppCount.get(group.getName()), - R.string.app_permission_usage_bar_label); + R.string.app_permission_usage_bar_label, group.getLabel()); barViewInfo.setClickListener(v -> { mFilterGroup = group.getName(); -- GitLab From 500b0483b6a407b9bdf3a2ab42422fa80a5f0eaa Mon Sep 17 00:00:00 2001 From: Evan Severson Date: Tue, 5 Mar 2019 11:25:08 -0800 Subject: [PATCH 415/701] Changed dialog's title font to match theme Fixes: 126820791 Test: Default theme looks same Title font changes with theme Change-Id: I41632587eef5f7dd479c12126613eff5aeb160b1 --- res/values/styles.xml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/res/values/styles.xml b/res/values/styles.xml index 7e8a135ad..dbffd5486 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -74,13 +74,10 @@ - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java index b40eb9c75..d9ea735b9 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java @@ -179,7 +179,7 @@ public class AppPermissionFragment extends SettingsWithLargeHeader { String appLabel = Utils.getFullAppLabel(mGroup.getApp().applicationInfo, context); setHeader(getAppIcon(), appLabel, null); - updateHeader(root.requireViewById(R.id.button_header)); + updateHeader(root.requireViewById(R.id.large_header)); ((TextView) root.requireViewById(R.id.permission_message)).setText( context.getString(R.string.app_permission_header, mGroup.getLabel(), appLabel)); -- GitLab From c9d4d4c68f9a9559560cef22ec5bce61c0c95af3 Mon Sep 17 00:00:00 2001 From: Evan Severson Date: Thu, 14 Mar 2019 11:16:02 -0700 Subject: [PATCH 442/701] Allow multiple permissions in same group to auto grant Only ignore if group has been policy fixed and nothing is granted. Grant permission regardless of whether another permission in the group is already granted. Bug: 124453468 Test: Artificially set policy to auto grant and request multiple permissions from single group in a test app Change-Id: I805a3ebce4b2a3df4e6d023d780df534601ea6ca --- .../permission/ui/GrantPermissionsActivity.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java b/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java index 4cafbae9b..1ad5c8f38 100644 --- a/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java +++ b/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java @@ -154,7 +154,7 @@ public class GrantPermissionsActivity extends Activity reportRequestResult(permission, PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_USER_FIXED); return; - } else if (group.isPolicyFixed()) { + } else if (group.isPolicyFixed() && !group.areRuntimePermissionsGranted()) { reportRequestResult(permission, PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED_POLICY_FIXED); return; @@ -174,9 +174,7 @@ public class GrantPermissionsActivity extends Activity boolean skipGroup = false; switch (getPermissionPolicy()) { case DevicePolicyManager.PERMISSION_POLICY_AUTO_GRANT: { - if (!group.areRuntimePermissionsGranted()) { - group.grantRuntimePermissions(false, new String[]{permission}); - } + group.grantRuntimePermissions(false, new String[]{permission}); state.mState = GroupState.STATE_ALLOWED; group.setPolicyFixed(); skipGroup = true; -- GitLab From 563ca11b5fd6a59146219208cbffb9b41bf6eb0e Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Thu, 14 Mar 2019 17:02:54 -0700 Subject: [PATCH 443/701] Check for role visibility in more places. Bug: 124452117 Test: build Change-Id: Iea5d5e3801383058e585e0247a5392bd6577f246 --- .../packageinstaller/PackageInstallerApplication.java | 9 +++++---- src/com/android/packageinstaller/role/model/Role.java | 11 +++++++++++ .../role/service/RoleSearchIndexablesProvider.java | 4 ++++ .../packageinstaller/role/ui/RequestRoleActivity.java | 6 ++++++ 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/com/android/packageinstaller/PackageInstallerApplication.java b/src/com/android/packageinstaller/PackageInstallerApplication.java index 871cc35b4..a1aa539dc 100644 --- a/src/com/android/packageinstaller/PackageInstallerApplication.java +++ b/src/com/android/packageinstaller/PackageInstallerApplication.java @@ -38,23 +38,24 @@ public class PackageInstallerApplication extends Application { private void updateSpecialAppAccessListActivityEnabledState() { ArrayMap roles = Roles.get(this); - boolean hasSpecialAppAccess = false; + boolean hasVisibleSpecialAppAccess = false; int rolesSize = roles.size(); for (int i = 0; i < rolesSize; i++) { Role role = roles.valueAt(i); - if (!role.isAvailable(this)) { + if (!role.isAvailable(this) || !role.isVisible(this)) { continue; } if (!role.isExclusive()) { - hasSpecialAppAccess = true; + hasVisibleSpecialAppAccess = true; break; } } PackageManager packageManager = getPackageManager(); ComponentName componentName = new ComponentName(this, SpecialAppAccessListActivity.class); - int enabledState = hasSpecialAppAccess ? PackageManager.COMPONENT_ENABLED_STATE_DEFAULT + int enabledState = hasVisibleSpecialAppAccess + ? PackageManager.COMPONENT_ENABLED_STATE_DEFAULT : PackageManager.COMPONENT_ENABLED_STATE_DISABLED; packageManager.setComponentEnabledSetting(componentName, enabledState, PackageManager.DONT_KILL_APP); diff --git a/src/com/android/packageinstaller/role/model/Role.java b/src/com/android/packageinstaller/role/model/Role.java index 89837d387..86842f61a 100644 --- a/src/com/android/packageinstaller/role/model/Role.java +++ b/src/com/android/packageinstaller/role/model/Role.java @@ -261,6 +261,17 @@ public class Role { return true; } + /** + * Check whether this role should be visible to user, for current user. + * + * @param context the {@code Context} to retrieve system services + * + * @return whether this role should be visible to user. + */ + public boolean isVisible(@NonNull Context context) { + return isVisibleAsUser(Process.myUserHandle(), context); + } + /** * Get the {@link Intent} to manage this role, or {@code null} to use the default UI. * diff --git a/src/com/android/packageinstaller/role/service/RoleSearchIndexablesProvider.java b/src/com/android/packageinstaller/role/service/RoleSearchIndexablesProvider.java index d105f58c0..55076278c 100644 --- a/src/com/android/packageinstaller/role/service/RoleSearchIndexablesProvider.java +++ b/src/com/android/packageinstaller/role/service/RoleSearchIndexablesProvider.java @@ -50,6 +50,10 @@ public class RoleSearchIndexablesProvider extends BaseSearchIndexablesProvider { for (int i = 0; i < rolesSize; i++) { Role role = roles.valueAt(i); + if (!role.isAvailable(context) || !role.isVisible(context)) { + continue; + } + String label = context.getString(role.getLabelResource()); boolean isExclusive = role.isExclusive(); cursor.newRow() diff --git a/src/com/android/packageinstaller/role/ui/RequestRoleActivity.java b/src/com/android/packageinstaller/role/ui/RequestRoleActivity.java index e6fb868a3..2f991ac46 100644 --- a/src/com/android/packageinstaller/role/ui/RequestRoleActivity.java +++ b/src/com/android/packageinstaller/role/ui/RequestRoleActivity.java @@ -83,6 +83,12 @@ public class RequestRoleActivity extends FragmentActivity { return; } + if (!role.isVisible(this)) { + Log.e(LOG_TAG, "Role is invisible: " + mRoleName); + finish(); + return; + } + if (PackageUtils.getApplicationInfo(mPackageName, this) == null) { Log.w(LOG_TAG, "Unknown application: " + mPackageName); finish(); -- GitLab From 2ae3dd803e28639baff1c3df58e50f154bc32a5f Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Thu, 14 Mar 2019 17:26:13 -0700 Subject: [PATCH 444/701] Scale permission icons down to 24dp. Bug: 128438946 Test: View all icons in ManagePermissionsFragment. Change-Id: Ib007fc571cc8e12db2de6c7603495bcd426adb65 --- res/values/dimens.xml | 2 ++ .../permission/ui/handheld/ManagePermissionsFragment.java | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 0412dcc2d..702fe13d7 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -23,6 +23,8 @@ 16dp 16dp + 24dp + 384dp 576dp diff --git a/src/com/android/packageinstaller/permission/ui/handheld/ManagePermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/ManagePermissionsFragment.java index d41df26ad..cf2c56fea 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/ManagePermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/ManagePermissionsFragment.java @@ -173,7 +173,7 @@ abstract class ManagePermissionsFragment extends PermissionsFrameFragment ImageView icon = ((ImageView) holder.findViewById(android.R.id.icon)); icon.setAdjustViewBounds(true); int size = getContext().getResources().getDimensionPixelSize( - R.dimen.secondary_app_icon_size); + R.dimen.permission_icon_size); icon.setMaxWidth(size); icon.setMaxHeight(size); icon.getLayoutParams().width = size; -- GitLab From 593dea0c95eb3528a5eb3ca4a9d02625d4607670 Mon Sep 17 00:00:00 2001 From: Eugene Susla Date: Thu, 14 Mar 2019 15:49:05 -0700 Subject: [PATCH 445/701] Fallback to default on null dialer Bug: 123637623 Test: set dialer to null, than flash fix end ensure it's no longer null Change-Id: I2b6610cad89d880dacabdadc2b92291ef5083110 --- .../packageinstaller/role/model/DialerRoleBehavior.java | 8 +++----- src/com/android/packageinstaller/role/model/Role.java | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/com/android/packageinstaller/role/model/DialerRoleBehavior.java b/src/com/android/packageinstaller/role/model/DialerRoleBehavior.java index 3a87c18af..c95d9100d 100644 --- a/src/com/android/packageinstaller/role/model/DialerRoleBehavior.java +++ b/src/com/android/packageinstaller/role/model/DialerRoleBehavior.java @@ -23,8 +23,6 @@ import android.telephony.TelephonyManager; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import java.util.List; - /** * Class for behavior of the dialer role. * @@ -49,9 +47,9 @@ public class DialerRoleBehavior implements RoleBehavior { context); } - @NonNull + @Nullable @Override - public List getDefaultHolders(@NonNull Role role, @NonNull Context context) { - return ExclusiveDefaultHolderMixin.getDefaultHolders(role, "config_defaultDialer", context); + public String getFallbackHolder(@NonNull Role role, @NonNull Context context) { + return ExclusiveDefaultHolderMixin.getDefaultHolder(role, "config_defaultDialer", context); } } diff --git a/src/com/android/packageinstaller/role/model/Role.java b/src/com/android/packageinstaller/role/model/Role.java index d2c32b811..5f5fb5cbd 100644 --- a/src/com/android/packageinstaller/role/model/Role.java +++ b/src/com/android/packageinstaller/role/model/Role.java @@ -232,7 +232,7 @@ public class Role { /** * Get the fallback holder of this role, which will be added whenever there are no role holders. *

- * Should return empty if this role {@link #mShowNone shows a "None" item}. + * Should return {@code null} if this role {@link #mShowNone shows a "None" item}. * * @param context the {@code Context} to retrieve system services * -- GitLab From c7900f3d2995bae7c2b3fce078644d408d264bd5 Mon Sep 17 00:00:00 2001 From: Evan Severson Date: Fri, 15 Mar 2019 11:48:54 -0700 Subject: [PATCH 446/701] Make AppPermissionSelection resizable I mistakenly forgot to add this in http://ag/6717874 Test: Build Change-Id: I77788161da62d4bab2275141a5235524a581bf5f --- res/layout/app_permission.xml | 2 -- res/values/styles.xml | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/res/layout/app_permission.xml b/res/layout/app_permission.xml index 0472f1463..fb8e0e1f2 100644 --- a/res/layout/app_permission.xml +++ b/res/layout/app_permission.xml @@ -36,8 +36,6 @@ - + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java index b3929d7d0..98d2ecb25 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java @@ -37,7 +37,9 @@ import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemSelectedListener; +import android.widget.ImageView; import android.widget.Spinner; +import android.widget.TextView; import androidx.annotation.IntDef; import androidx.annotation.NonNull; @@ -126,6 +128,8 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements private Spinner mSortSpinner; private FilterSpinnerAdapter mSortAdapter; + private ArrayMap mGroupAppCounts; + private boolean mFinishedInitialLoad; /** @@ -380,6 +384,7 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements long startTime = (timeFilterItem == null ? 0 : (curTime - timeFilterItem.getTime())); List> usages = new ArrayList<>(); + mGroupAppCounts = new ArrayMap<>(); ArrayList permApps = new ArrayList<>(); int numApps = appPermissionUsages.size(); for (int appNum = 0; appNum < numApps; appNum++) { @@ -412,9 +417,12 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements usages.add(Pair.create(appUsage, appGroups.get(groupNum))); used = true; + + addGroupUser(groupUsage.getGroup().getName()); } if (used) { permApps.add(appUsage.getApp()); + addGroupUser(null); } } @@ -513,6 +521,15 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements return mSortAdapter.getFilter(pos).getSortOption(); } + private void addGroupUser(String app) { + Integer count = mGroupAppCounts.get(app); + if (count == null) { + mGroupAppCounts.put(app, 1); + } else { + mGroupAppCounts.put(app, count + 1); + } + } + /** * Reloads the data to show. */ @@ -829,14 +846,24 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements // Create the spinner entries. String[] groupNames = new String[groups.size() + 1]; CharSequence[] groupLabels = new CharSequence[groupNames.length]; + int[] groupIcons = new int[groupNames.length]; + int[] groupAccessCounts = new int[groupNames.length]; groupNames[0] = null; groupLabels[0] = context.getString(R.string.permission_usage_any_permission); + groupIcons[0] = 0; + groupAccessCounts[0] = mGroupAppCounts.get(null); int selection = 0; int numGroups = groups.size(); for (int i = 0; i < numGroups; i++) { AppPermissionGroup group = groups.get(i); groupNames[i + 1] = group.getName(); groupLabels[i + 1] = group.getLabel(); + groupIcons[i + 1] = group.getIconResId(); + Integer appCount = mGroupAppCounts.get(group.getName()); + if (appCount == null) { + appCount = 0; + } + groupAccessCounts[i + 1] = appCount; if (group.getName().equals(mFilterGroup)) { selection = i + 1; } @@ -849,6 +876,8 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements args.putCharSequenceArray(PermissionsFilterDialog.ELEMS, groupLabels); args.putInt(PermissionsFilterDialog.SELECTION, selection); args.putStringArray(PermissionsFilterDialog.GROUPS, groupNames); + args.putIntArray(PermissionsFilterDialog.ICONS, groupIcons); + args.putIntArray(PermissionsFilterDialog.ACCESS_COUNTS, groupAccessCounts); PermissionsFilterDialog chooserDialog = new PermissionsFilterDialog(); chooserDialog.setArguments(args); chooserDialog.setTargetFragment(this, 0); @@ -880,22 +909,54 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements + ".arg.selection"; private static final String GROUPS = PermissionsFilterDialog.class.getName() + ".arg.groups"; + private static final String ICONS = PermissionsFilterDialog.class.getName() + + ".arg.icons"; + private static final String ACCESS_COUNTS = PermissionsFilterDialog.class.getName() + + ".arg.access_counts"; @Override public Dialog onCreateDialog(Bundle savedInstanceState) { + AlertDialog.Builder b = new AlertDialog.Builder(getActivity()) + .setView(createDialogView()); + + return b.create(); + } + + private @NonNull View createDialogView() { PermissionUsageFragment fragment = (PermissionUsageFragment) getTargetFragment(); CharSequence[] elems = getArguments().getCharSequenceArray(ELEMS); String[] groups = getArguments().getStringArray(GROUPS); - AlertDialog.Builder b = new AlertDialog.Builder(getActivity()) - .setTitle(getArguments().getCharSequence(TITLE)) - .setSingleChoiceItems(elems, getArguments().getInt(SELECTION), - (dialog, which) -> { - dismissAllowingStateLoss(); - fragment.onPermissionGroupSelected(groups[which]); - } - ); + int[] icons = getArguments().getIntArray(ICONS); + int[] accessCounts = getArguments().getIntArray(ACCESS_COUNTS); + + LayoutInflater layoutInflater = LayoutInflater.from(fragment.getActivity()); + View view = layoutInflater.inflate(R.layout.permission_filter_dialog, null); + ViewGroup itemsListView = view.requireViewById(R.id.items_container); + + ((TextView) view.requireViewById(R.id.title)).setText( + getArguments().getCharSequence(TITLE)); + + for (int i = 0; i < elems.length; i++) { + String groupName = groups[i]; + View itemView = layoutInflater.inflate(R.layout.permission_filter_dialog_item, + itemsListView, false); + + ((ImageView) itemView.requireViewById(R.id.icon)).setImageResource(icons[i]); + ((TextView) itemView.requireViewById(R.id.title)).setText(elems[i]); + ((TextView) itemView.requireViewById(R.id.summary)).setText( + getActivity().getResources().getQuantityString( + R.plurals.permission_usage_permission_filter_subtitle, + accessCounts[i], accessCounts[i])); + + itemView.setOnClickListener((v) -> { + dismissAllowingStateLoss(); + fragment.onPermissionGroupSelected(groupName); + }); - return b.create(); + itemsListView.addView(itemView); + } + + return view; } } -- GitLab From b092882decedd2a8436d3b07dfb26f5fba6a77db Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Mon, 18 Mar 2019 16:49:28 -0700 Subject: [PATCH 455/701] Correctly determine emergency role availability. Report emergency role availability according to TelephonyManager.EMERGENCY_ASSISTANCE_ENABLED as well. Bug: 124452117 Test: build Change-Id: Ib96a04ce15aaa24f7aa772b652a5cd2ea0e1a2b4 --- AndroidManifest.xml | 1 + .../packageinstaller/role/model/EmergencyRoleBehavior.java | 4 +--- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 9914e344e..243a347cb 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -35,6 +35,7 @@ + diff --git a/src/com/android/packageinstaller/role/model/EmergencyRoleBehavior.java b/src/com/android/packageinstaller/role/model/EmergencyRoleBehavior.java index 0f5875de2..90a65d8cf 100644 --- a/src/com/android/packageinstaller/role/model/EmergencyRoleBehavior.java +++ b/src/com/android/packageinstaller/role/model/EmergencyRoleBehavior.java @@ -41,10 +41,8 @@ public class EmergencyRoleBehavior implements RoleBehavior { @Override public boolean isAvailableAsUser(@NonNull Role role, @NonNull UserHandle user, @NonNull Context context) { - // TODO: STOPSHIP: Also TelephonyManager.EMERGENCY_ASSISTANCE_ENABLED, and a boolean - // constant to disable UI by default. TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class); - return telephonyManager.isVoiceCapable(); + return telephonyManager.isEmergencyAssistanceEnabled() && telephonyManager.isVoiceCapable(); } @Nullable -- GitLab From 1a1f3612af3bf131fce1c795591f17dd14950432 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Fri, 22 Feb 2019 11:03:32 -0800 Subject: [PATCH 456/701] Add a header showing the permission name, icon, and description to PermissionAppsFragment. Fixes: 124677177 Test: Open screen and see description. Change-Id: Idbc2bc041bf4792a99d7d34fe0eaf3bf866f6f62 --- res/values/strings.xml | 39 +++++++++++++++++ res/values/styles.xml | 2 + .../permission/model/PermissionApps.java | 11 +++++ .../ui/handheld/PermissionAppsFragment.java | 19 +++++--- .../ui/handheld/SettingsWithLargeHeader.java | 9 +++- .../permission/utils/Utils.java | 43 +++++++++++++++++++ 6 files changed, 117 insertions(+), 6 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 79cd62195..f414a5fa7 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -400,6 +400,45 @@ See all apps with the %1$s permission + + Apps with this permission can %1$s + + + Apps with this permission can recognize activity + + + Apps with this permission can access your calendar + + + Apps with this permission can read and write phone call log + + + Apps with this permission can take pictures and record video + + + Apps with this permission can access your contacts + + + Apps with this permission can access this device\'s location + + + Apps with this permission can access your music + + + Apps with this permission can access your photos & videos + + + Apps with this permission can record audio + + + Apps with this permission can make and manage phone calls + + + Apps with this permission can access sensor data about your vital signs + + + Apps with this permission can send and view SMS messages + Last access: %1$s diff --git a/res/values/styles.xml b/res/values/styles.xml index f96a94089..2138ceb61 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -196,6 +196,8 @@ wrap_content 16dp ?android:attr/colorAccent + ?android:attr/listPreferredItemPaddingStart + ?android:attr/listPreferredItemPaddingEnd @@ -282,6 +280,8 @@ 16dp 48dp 48dp + ?android:attr/listPreferredItemPaddingStart + ?android:attr/listPreferredItemPaddingEnd ?android:attr/textColorSecondary diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java index d9ea735b9..78e30b1c0 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java @@ -182,7 +182,7 @@ public class AppPermissionFragment extends SettingsWithLargeHeader { updateHeader(root.requireViewById(R.id.large_header)); ((TextView) root.requireViewById(R.id.permission_message)).setText( - context.getString(R.string.app_permission_header, mGroup.getLabel(), appLabel)); + context.getString(R.string.app_permission_header, mGroup.getLabel())); if (Utils.isModernPermissionGroup(mGroup.getName())) { String timeDiffStr = Utils.getRelativeLastUsageString(context, -- GitLab From 87faa85bc691b28d95b4f8f9e296a8a7efbcd5cd Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Wed, 20 Mar 2019 09:30:33 -0700 Subject: [PATCH 459/701] Modify ManagePermissionActivity to take in a permission not a group. This is a public API, so external callers should pass in permissions and not groups. Note that I kept AppPermissionFragment getting the group, as that's what it wants and the Activity needs to compute it anyway. Test: Open this page through Location settings and Permissions Controller screens. Test: Clicking on GMS Core's Location still pops up dialog. Change-Id: I22d2dc7dfc25b8871953d12de613006b26bc4365 --- .../permission/service/LocationAccessCheck.java | 4 +--- .../permission/ui/AppPermissionActivity.java | 8 +++++--- .../permission/ui/handheld/AppPermissionFragment.java | 6 +++--- .../ui/handheld/PermissionControlPreference.java | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/com/android/packageinstaller/permission/service/LocationAccessCheck.java b/src/com/android/packageinstaller/permission/service/LocationAccessCheck.java index c809981fc..b7c702c54 100644 --- a/src/com/android/packageinstaller/permission/service/LocationAccessCheck.java +++ b/src/com/android/packageinstaller/permission/service/LocationAccessCheck.java @@ -46,7 +46,6 @@ import static com.android.packageinstaller.Constants.PERIODIC_LOCATION_ACCESS_CH import static com.android.packageinstaller.Constants.PERMISSION_REMINDER_CHANNEL_ID; import static com.android.packageinstaller.Constants.PREFERENCES_FILE; import static com.android.packageinstaller.permission.utils.Utils.OS_PKG; -import static com.android.packageinstaller.permission.utils.Utils.getGroupOfPlatformPermission; import static com.android.packageinstaller.permission.utils.Utils.getParcelableExtraSafe; import static com.android.packageinstaller.permission.utils.Utils.getStringExtraSafe; import static com.android.packageinstaller.permission.utils.Utils.getSystemServiceSafe; @@ -837,8 +836,7 @@ public class LocationAccessCheck { Intent manageAppPermission = new Intent(context, AppPermissionActivity.class); manageAppPermission.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK); - manageAppPermission.putExtra(EXTRA_PERMISSION_NAME, - getGroupOfPlatformPermission(ACCESS_FINE_LOCATION)); + manageAppPermission.putExtra(EXTRA_PERMISSION_NAME, ACCESS_FINE_LOCATION); manageAppPermission.putExtra(EXTRA_PACKAGE_NAME, pkg); manageAppPermission.putExtra(EXTRA_USER, user); diff --git a/src/com/android/packageinstaller/permission/ui/AppPermissionActivity.java b/src/com/android/packageinstaller/permission/ui/AppPermissionActivity.java index e00c4c527..0295c7381 100644 --- a/src/com/android/packageinstaller/permission/ui/AppPermissionActivity.java +++ b/src/com/android/packageinstaller/permission/ui/AppPermissionActivity.java @@ -30,6 +30,7 @@ import androidx.fragment.app.FragmentActivity; import com.android.packageinstaller.DeviceUtils; import com.android.packageinstaller.permission.ui.handheld.AppPermissionFragment; import com.android.packageinstaller.permission.utils.LocationUtils; +import com.android.packageinstaller.permission.utils.Utils; /** * Manage a single permission of a single app @@ -56,6 +57,7 @@ public final class AppPermissionActivity extends FragmentActivity { finish(); return; } + String groupName = Utils.getGroupOfPlatformPermission(permissionName); UserHandle userHandle = getIntent().getParcelableExtra(Intent.EXTRA_USER); if (userHandle == null) { @@ -64,7 +66,7 @@ public final class AppPermissionActivity extends FragmentActivity { return; } - if (LocationUtils.isLocationGroupAndProvider(this, permissionName, + if (LocationUtils.isLocationGroupAndProvider(this, groupName, packageName)) { Intent intent = new Intent(this, LocationProviderInterceptDialog.class); intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName); @@ -74,14 +76,14 @@ public final class AppPermissionActivity extends FragmentActivity { } if (LocationUtils.isLocationGroupAndControllerExtraPackage( - this, permissionName, packageName)) { + this, groupName, packageName)) { // Redirect to location controller extra package settings. LocationUtils.startLocationControllerExtraPackageSettings(this); finish(); return; } - Fragment androidXFragment = AppPermissionFragment.newInstance(packageName, permissionName, + Fragment androidXFragment = AppPermissionFragment.newInstance(packageName, groupName, userHandle); getSupportFragmentManager().beginTransaction().replace(android.R.id.content, diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java index d9ea735b9..3f62f48c0 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java @@ -110,11 +110,11 @@ public class AppPermissionFragment extends SettingsWithLargeHeader { * @return A new fragment */ public static @NonNull AppPermissionFragment newInstance(@NonNull String packageName, - @NonNull String permissionName, @NonNull UserHandle userHandle) { + @NonNull String groupName, @NonNull UserHandle userHandle) { AppPermissionFragment fragment = new AppPermissionFragment(); Bundle arguments = new Bundle(); arguments.putString(Intent.EXTRA_PACKAGE_NAME, packageName); - arguments.putString(Intent.EXTRA_PERMISSION_NAME, permissionName); + arguments.putString(Intent.EXTRA_PERMISSION_GROUP_NAME, groupName); arguments.putParcelable(Intent.EXTRA_USER, userHandle); fragment.setArguments(arguments); return fragment; @@ -145,7 +145,7 @@ public class AppPermissionFragment extends SettingsWithLargeHeader { Context context = getPreferenceManager().getContext(); String packageName = getArguments().getString(Intent.EXTRA_PACKAGE_NAME); - String groupName = getArguments().getString(Intent.EXTRA_PERMISSION_NAME); + String groupName = getArguments().getString(Intent.EXTRA_PERMISSION_GROUP_NAME); PackageItemInfo groupInfo = Utils.getGroupInfo(groupName, context); List groupPermInfos = Utils.getGroupPermissionInfos(groupName, context); if (groupInfo == null || groupPermInfos == null) { diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionControlPreference.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionControlPreference.java index 940487c88..5e307ea20 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionControlPreference.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionControlPreference.java @@ -61,7 +61,7 @@ public class PermissionControlPreference extends Preference { setOnPreferenceClickListener(preference -> { Intent intent = new Intent(context, AppPermissionActivity.class); intent.putExtra(Intent.EXTRA_PACKAGE_NAME, group.getApp().packageName); - intent.putExtra(Intent.EXTRA_PERMISSION_NAME, group.getName()); + intent.putExtra(Intent.EXTRA_PERMISSION_NAME, group.getPermissions().get(0).getName()); intent.putExtra(Intent.EXTRA_USER, group.getUser()); context.startActivity(intent); return true; -- GitLab From 035cf6bd5b547856bb9c55932ad948ad7654ad64 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Mon, 18 Mar 2019 13:53:33 -0700 Subject: [PATCH 460/701] Update Permissions Hub to the newest design. - Remove the bar chart. - Add a menu option to control whether we sort by most recently used apps or by time. - Change the default sort option to be by most recently used apps. - Show permission names instead of icons in the parent summaries and ellipsize them on overflow. - Change sort by app to sort by apps with recent usages instead of apps with the most permissions accessed. - Modify the access string to show whether the access was in the foreground or the background. - Show a gear icon on the right of the access preferences. - Fix a bug where usage entries were not vertically centered. Bug: 128521173 Test: View screen. Change-Id: I3e9423884d56bb35cfbb040c7aa208afb998da73 --- PermissionController.mk | 1 - res/layout/preference_usage.xml | 18 +- res/values/strings.xml | 46 ++-- .../permission/model/AppPermissionUsage.java | 54 +++-- .../handheld/ExpandablePreferenceGroup.java | 6 + .../permission/ui/handheld/FilterSpinner.java | 15 +- .../handheld/PermissionControlPreference.java | 11 +- .../ui/handheld/PermissionUsageFragment.java | 199 +++++++----------- 8 files changed, 158 insertions(+), 192 deletions(-) diff --git a/PermissionController.mk b/PermissionController.mk index 6ecd5eb87..6b5ff81e8 100644 --- a/PermissionController.mk +++ b/PermissionController.mk @@ -32,7 +32,6 @@ LOCAL_STATIC_ANDROID_LIBRARIES += \ SettingsLibSearchWidget \ SettingsLibSettingsSpinner \ SettingsLibLayoutPreference \ - SettingsLibBarChartPreference \ SettingsLibActionBarShadow \ SettingsLibProgressBar diff --git a/res/layout/preference_usage.xml b/res/layout/preference_usage.xml index 821398c67..6ff031786 100644 --- a/res/layout/preference_usage.xml +++ b/res/layout/preference_usage.xml @@ -20,8 +20,8 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" - android:paddingTop="14dp" - android:paddingBottom="14dp" + android:paddingTop="12dp" + android:paddingBottom="12dp" android:minHeight="?android:attr/listPreferredItemHeightSmall" android:gravity="center_vertical" android:paddingLeft="?android:attr/listPreferredItemPaddingLeft" @@ -57,8 +57,7 @@ android:singleLine="true" android:textAppearance="?android:attr/textAppearanceListItem" android:ellipsize="marquee" - app:layout_constraintStart_toEndOf="@+id/title_widget_frame" - app:layout_constraintTop_toTopOf="@+id/image_frame_include"/> + app:layout_constraintStart_toEndOf="@+id/title_widget_frame"/> + app:layout_constraintTop_toBottomOf="@android:id/title" + app:layout_constraintEnd_toStartOf="@android:id/widget_frame"/> + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent"/> diff --git a/res/values/strings.xml b/res/values/strings.xml index 1ab952ee9..b32a1da2f 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -262,8 +262,11 @@ Dashboard - - Last access: %1$s + + Last access: %1$s <font color="#0f9d58">(while the app was in use)</font> + + + Last access: %1$s (in the background) Any permission @@ -290,40 +293,22 @@ No permission usages - Access at any time + Most recent access at any time - Access in last 7 days + Most recent access in last 7 days - Access in last 24 hours + Most recent access in last 24 hours - Access in the last hour + Most recent access in the last hour - Access in last 15 minutes + A=Most recent access in last 15 minutes - Access in last 1 minute - - - Top permission usage at any time - - - Top permission usage in last 7 days - - - Top permission usage in last 24 hours - - - Top permission usage in last 1 hour - - - Top permission usage in last 15 minutes - - - Top permission usage in last 1 minute + Most recent access in last 1 minute Apps @@ -349,6 +334,15 @@ Recent + + Sort by app usage + + + Sort by time + + + ,\u0020 + Refresh diff --git a/src/com/android/packageinstaller/permission/model/AppPermissionUsage.java b/src/com/android/packageinstaller/permission/model/AppPermissionUsage.java index b69392c5d..f1b742d56 100644 --- a/src/com/android/packageinstaller/permission/model/AppPermissionUsage.java +++ b/src/com/android/packageinstaller/permission/model/AppPermissionUsage.java @@ -20,13 +20,12 @@ import android.app.AppOpsManager; import android.app.AppOpsManager.HistoricalOp; import android.app.AppOpsManager.HistoricalPackageOps; import android.app.AppOpsManager.OpEntry; - import android.app.AppOpsManager.PackageOps; import androidx.annotation.NonNull; import androidx.annotation.Nullable; + import com.android.packageinstaller.permission.model.PermissionApps.PermissionApp; -import com.android.packageinstaller.permission.utils.Utils; import java.util.ArrayList; import java.util.List; @@ -107,25 +106,25 @@ public final class AppPermissionUsage { if (mLastUsage == null) { return 0; } - long lastAccessTime = 0; - final ArrayList permissions = mGroup.getPermissions(); - final int permissionCount = permissions.size(); - for (int i = 0; i < permissionCount; i++) { - final Permission permission = permissions.get(i); - final String opName = permission.getAppOp(); - final List ops = mLastUsage.getOps(); - final int opCount = ops.size(); - for (int j = 0; j < opCount; j++) { - final OpEntry op = ops.get(j); - if (op.getOpStr().equals(opName)) { - lastAccessTime = Math.max(lastAccessTime, - op.getLastAccessTime(AppOpsManager.OP_FLAGS_ALL_TRUSTED)); - } - } + return lastAccessAggregate( + (op) -> op.getLastAccessTime(AppOpsManager.OP_FLAGS_ALL_TRUSTED)); + } + + public long getLastAccessForegroundTime() { + if (mLastUsage == null) { + return 0; } - return lastAccessTime; + return lastAccessAggregate( + (op) -> op.getLastAccessForegroundTime(AppOpsManager.OP_FLAGS_ALL_TRUSTED)); } + public long getLastAccessBackgroundTime() { + if (mLastUsage == null) { + return 0; + } + return lastAccessAggregate( + (op) -> op.getLastAccessBackgroundTime(AppOpsManager.OP_FLAGS_ALL_TRUSTED)); + } public long getForegroundAccessCount() { if (mHistoricalUsage == null) { @@ -178,6 +177,25 @@ public final class AppPermissionUsage { return aggregate; } + private long lastAccessAggregate(@NonNull Function extractor) { + long aggregate = 0; + final ArrayList permissions = mGroup.getPermissions(); + final int permissionCount = permissions.size(); + for (int permissionNum = 0; permissionNum < permissionCount; permissionNum++) { + final Permission permission = permissions.get(permissionNum); + final String opName = permission.getAppOp(); + final List ops = mLastUsage.getOps(); + final int opCount = ops.size(); + for (int opNum = 0; opNum < opCount; opNum++) { + final OpEntry op = ops.get(opNum); + if (op.getOpStr().equals(opName)) { + aggregate = Math.max(aggregate, extractor.apply(op)); + } + } + } + return aggregate; + } + public @NonNull AppPermissionGroup getGroup() { return mGroup; } diff --git a/src/com/android/packageinstaller/permission/ui/handheld/ExpandablePreferenceGroup.java b/src/com/android/packageinstaller/permission/ui/handheld/ExpandablePreferenceGroup.java index 3e5bf793b..49a2d5f64 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/ExpandablePreferenceGroup.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/ExpandablePreferenceGroup.java @@ -17,11 +17,13 @@ package com.android.packageinstaller.permission.ui.handheld; import android.content.Context; +import android.text.TextUtils; import android.util.Pair; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; +import android.widget.TextView; import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; @@ -78,6 +80,10 @@ public class ExpandablePreferenceGroup extends PreferenceGroup { super.onBindViewHolder(holder); + TextView summary = (TextView) holder.findViewById(android.R.id.summary); + summary.setMaxLines(1); + summary.setEllipsize(TextUtils.TruncateAt.END); + ImageView rightImageView = holder.findViewById( android.R.id.widget_frame).findViewById(R.id.icon); if (mExpanded) { diff --git a/src/com/android/packageinstaller/permission/ui/handheld/FilterSpinner.java b/src/com/android/packageinstaller/permission/ui/handheld/FilterSpinner.java index 6b1c0e47c..0380e7d4f 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/FilterSpinner.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/FilterSpinner.java @@ -109,14 +109,11 @@ public class FilterSpinner { public static class TimeFilterItem implements SpinnerItem { private final long mTime; private final @NonNull String mLabel; - private final @StringRes int mGraphTitleRes; private final @StringRes int mListTitleRes; - TimeFilterItem(long time, @NonNull String label, @StringRes int graphTitleRes, - @StringRes int listTitleRes) { + TimeFilterItem(long time, @NonNull String label, @StringRes int listTitleRes) { mTime = time; mLabel = label; - mGraphTitleRes = graphTitleRes; mListTitleRes = listTitleRes; } @@ -133,10 +130,6 @@ public class FilterSpinner { return mLabel; } - public @StringRes int getGraphTitleRes() { - return mGraphTitleRes; - } - public @StringRes int getListTitleRes() { return mListTitleRes; } @@ -152,27 +145,21 @@ public class FilterSpinner { @NonNull Context context) { adapter.addFilter(new TimeFilterItem(Long.MAX_VALUE, context.getString(R.string.permission_usage_any_time), - R.string.permission_usage_bar_chart_title_any_time, R.string.permission_usage_list_title_any_time)); adapter.addFilter(new TimeFilterItem(DAYS.toMillis(7), context.getString(R.string.permission_usage_last_7_days), - R.string.permission_usage_bar_chart_title_last_7_days, R.string.permission_usage_list_title_last_7_days)); adapter.addFilter(new TimeFilterItem(DAYS.toMillis(1), context.getString(R.string.permission_usage_last_day), - R.string.permission_usage_bar_chart_title_last_day, R.string.permission_usage_list_title_last_day)); adapter.addFilter(new TimeFilterItem(HOURS.toMillis(1), context.getString(R.string.permission_usage_last_hour), - R.string.permission_usage_bar_chart_title_last_hour, R.string.permission_usage_list_title_last_hour)); adapter.addFilter(new TimeFilterItem(MINUTES.toMillis(15), context.getString(R.string.permission_usage_last_15_minutes), - R.string.permission_usage_bar_chart_title_last_15_minutes, R.string.permission_usage_list_title_last_15_minutes)); adapter.addFilter(new TimeFilterItem(MINUTES.toMillis(1), context.getString(R.string.permission_usage_last_minute), - R.string.permission_usage_bar_chart_title_last_minute, R.string.permission_usage_list_title_last_minute)); } } diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionControlPreference.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionControlPreference.java index 940487c88..9ca01a843 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionControlPreference.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionControlPreference.java @@ -19,6 +19,7 @@ package com.android.packageinstaller.permission.ui.handheld; import android.content.Context; import android.content.Intent; import android.graphics.drawable.Drawable; +import android.text.Html; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; @@ -121,7 +122,15 @@ public class PermissionControlPreference extends Preference { * @param accessTimeStr the string representing the last access time */ public void setUsageSummary(@NonNull GroupUsage groupUsage, @NonNull String accessTimeStr) { - setSummary(mContext.getString(R.string.permission_usage_summary, accessTimeStr)); + if (groupUsage.getLastAccessForegroundTime() >= groupUsage.getLastAccessBackgroundTime()) { + setSummary(Html.fromHtml( + mContext.getString(R.string.permission_usage_summary_foreground, + accessTimeStr))); + } else { + setSummary(Html.fromHtml( + mContext.getString(R.string.permission_usage_summary_background, + accessTimeStr))); + } } /** diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java index 98d2ecb25..b975fb7e5 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java @@ -23,7 +23,6 @@ import android.app.AlertDialog; import android.app.Dialog; import android.content.Context; import android.content.Intent; -import android.graphics.drawable.Drawable; import android.os.Bundle; import android.util.ArrayMap; import android.util.ArraySet; @@ -60,9 +59,6 @@ import com.android.packageinstaller.permission.ui.handheld.FilterSpinner.TimeFil import com.android.packageinstaller.permission.utils.Utils; import com.android.permissioncontroller.R; import com.android.settingslib.HelpUtils; -import com.android.settingslib.widget.BarChartInfo; -import com.android.settingslib.widget.BarChartPreference; -import com.android.settingslib.widget.BarViewInfo; import java.lang.annotation.Retention; import java.text.Collator; @@ -83,13 +79,15 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements private static final String LOG_TAG = "PermissionUsageFragment"; @Retention(SOURCE) - @IntDef(value = {SORT_RECENT, SORT_MOST_PERMISSIONS}) + @IntDef(value = {SORT_RECENT, SORT_RECENT_APPS}) @interface SortOption {} static final int SORT_RECENT = 1; - static final int SORT_MOST_PERMISSIONS = 2; + static final int SORT_RECENT_APPS = 2; - private static final int MENU_FILTER_BY_PERMISSIONS = MENU_HIDE_SYSTEM + 1; - private static final int MENU_REFRESH = MENU_HIDE_SYSTEM + 2; + private static final int MENU_SORT_BY_APP = MENU_HIDE_SYSTEM + 1; + private static final int MENU_SORT_BY_TIME = MENU_HIDE_SYSTEM + 2; + private static final int MENU_FILTER_BY_PERMISSIONS = MENU_HIDE_SYSTEM + 3; + private static final int MENU_REFRESH = MENU_HIDE_SYSTEM + 4; private static final String KEY_SHOW_SYSTEM_PREFS = "_show_system"; private static final String SHOW_SYSTEM_KEY = PermissionUsageFragment.class.getName() @@ -107,11 +105,6 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements private static final String FINISHED_INITIAL_LOAD_KEY = PermissionUsageFragment.class.getName() + KEY_FINISHED_INITIAL_LOAD; - /** - * The maximum number of columns shown in the bar chart. - */ - private static final int MAXIMUM_NUM_BARS = 4; - private @NonNull PermissionUsages mPermissionUsages; private Collator mCollator; @@ -122,6 +115,8 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements private boolean mHasSystemApps; private MenuItem mShowSystemMenu; private MenuItem mHideSystemMenu; + private MenuItem mSortByApp; + private MenuItem mSortByTime; private Spinner mFilterSpinnerTime; private FilterSpinnerAdapter mFilterAdapterTime; @@ -179,6 +174,7 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + mSavedSortSpinnerIndex = 1; if (savedInstanceState != null) { mShowSystem = savedInstanceState.getBoolean(SHOW_SYSTEM_KEY); mSavedGroupName = savedInstanceState.getString(PERMS_INDEX_KEY); @@ -235,7 +231,7 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements SORT_RECENT)); mSortAdapter.addFilter( new SortItem(context.getString(R.string.sort_spinner_most_permissions), - SORT_MOST_PERMISSIONS)); + SORT_RECENT_APPS)); mSortSpinner.setSelection(mSavedSortSpinnerIndex); // STOPSHIP: Re-enable spinners afetr user study completes. @@ -292,13 +288,14 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { super.onCreateOptionsMenu(menu, inflater); + mSortByApp = menu.add(Menu.NONE, MENU_SORT_BY_APP, Menu.NONE, R.string.sort_by_app); + mSortByTime = menu.add(Menu.NONE, MENU_SORT_BY_TIME, Menu.NONE, R.string.sort_by_time); menu.add(Menu.NONE, MENU_FILTER_BY_PERMISSIONS, Menu.NONE, R.string.filter_by_permissions); if (mHasSystemApps) { mShowSystemMenu = menu.add(Menu.NONE, MENU_SHOW_SYSTEM, Menu.NONE, R.string.menu_show_system); mHideSystemMenu = menu.add(Menu.NONE, MENU_HIDE_SYSTEM, Menu.NONE, R.string.menu_hide_system); - updateMenu(); } HelpUtils.prepareHelpMenuItem(getActivity(), menu, R.string.help_permission_usage, getClass().getName()); @@ -306,6 +303,7 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements R.string.permission_usage_refresh); refresh.setIcon(R.drawable.ic_refresh); refresh.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); + updateMenu(); } @Override @@ -314,6 +312,16 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements case android.R.id.home: getActivity().finish(); return true; + case MENU_SORT_BY_APP: + mSortSpinner.setSelection(1); + updateUI(); + updateMenu(); + break; + case MENU_SORT_BY_TIME: + mSortSpinner.setSelection(0); + updateUI(); + updateMenu(); + break; case MENU_FILTER_BY_PERMISSIONS: showPermissionFilterDialog(); break; @@ -332,8 +340,12 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements } private void updateMenu() { - mShowSystemMenu.setVisible(!mShowSystem); - mHideSystemMenu.setVisible(mShowSystem); + if (mHasSystemApps) { + mShowSystemMenu.setVisible(!mShowSystem); + mHideSystemMenu.setVisible(mShowSystem); + } + mSortByApp.setVisible(mSortSpinner.getSelectedItemPosition() == 0); + mSortByTime.setVisible(mSortSpinner.getSelectedItemPosition() == 1); } @Override @@ -428,8 +440,6 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements // Update header. if (mFilterGroup == null) { - final BarChartPreference barChart = createBarChart(usages, timeFilterItem, context); - screen.addPreference(barChart); hideHeader(); } else { AppPermissionGroup group = getGroup(mFilterGroup); @@ -457,8 +467,8 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements final int sortOption = getSelectedSortOption(); if (sortOption == SORT_RECENT) { usages.sort(PermissionUsageFragment::compareAccessRecency); - } else if (sortOption == SORT_MOST_PERMISSIONS) { - usages.sort(PermissionUsageFragment::compareAccessUsage); + } else if (sortOption == SORT_RECENT_APPS) { + usages.sort(PermissionUsageFragment::compareAccessAppRecency); } else { Log.w(LOG_TAG, "Unexpected sort option: " + sortOption); } @@ -474,6 +484,8 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements new PermissionApps.AppDataLoader(context, () -> { ExpandablePreferenceGroup parent = null; AppPermissionUsage lastAppPermissionUsage = null; + String lastAccessTimeString = null; + List groups = new ArrayList<>(); final int numUsages = usages.size(); for (int usageNum = 0; usageNum < numUsages; usageNum++) { @@ -483,20 +495,25 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements String accessTimeString = Utils.getAbsoluteLastUsageString(context, groupUsage); - if (lastAppPermissionUsage != appPermissionUsage) { + if (lastAppPermissionUsage != appPermissionUsage || (sortOption == SORT_RECENT + && !accessTimeString.equals(lastAccessTimeString))) { + setPermissionSummary(parent, groups); // Add a "parent" entry for the app that will expand to the individual entries. parent = createExpandablePreferenceGroup(context, appPermissionUsage, sortOption == SORT_RECENT ? accessTimeString : null); category.addPreference(parent); lastAppPermissionUsage = appPermissionUsage; + groups = new ArrayList<>(); } parent.addPreference(createPermissionUsagePreference(context, appPermissionUsage, groupUsage, accessTimeString)); - parent.addSummaryIcon(groupUsage.getGroup().getIconResId(), - groupUsage.getGroup().getLabel()); + groups.add(groupUsage.getGroup().getLabel()); + lastAccessTimeString = accessTimeString; } + setPermissionSummary(parent, groups); + setLoading(false, true); mFinishedInitialLoad = true; setProgressBarVisible(false); @@ -516,7 +533,7 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements private int getSelectedSortOption() { final int pos = mSortSpinner.getSelectedItemPosition(); if (pos == AdapterView.INVALID_POSITION) { - return SORT_MOST_PERMISSIONS; + return SORT_RECENT_APPS; } return mSortAdapter.getFilter(pos).getSortOption(); } @@ -530,6 +547,22 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements } } + private void setPermissionSummary(@NonNull ExpandablePreferenceGroup pref, + @NonNull List groups) { + if (pref == null) { + return; + } + StringBuilder sb = new StringBuilder(); + int numGroups = groups.size(); + for (int i = 0; i < numGroups; i++) { + sb.append(groups.get(i)); + if (i < numGroups - 1) { + sb.append(getString(R.string.item_separator)); + } + } + pref.setSummary(sb.toString()); + } + /** * Reloads the data to show. */ @@ -550,71 +583,6 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements } } - /** - * Create a bar chart showing the permissions that are used by the most apps. - * - * @param usages the usages - * @param timeFilterItem the time filter, or null if no filter is set - * @param context the context - * - * @return the Preference representing the bar chart - */ - private BarChartPreference createBarChart( - @NonNull List> usages, - @Nullable TimeFilterItem timeFilterItem, @NonNull Context context) { - BarChartInfo.Builder builder = new BarChartInfo.Builder(); - BarChartPreference barChart = new BarChartPreference(context, null); - if (timeFilterItem != null) { - builder.setTitle(timeFilterItem.getGraphTitleRes()); - } - - final ArrayList groups = new ArrayList<>(); - final ArrayMap groupToAppCount = new ArrayMap<>(); - final int usageCount = usages.size(); - for (int i = 0; i < usageCount; i++) { - final Pair usage = usages.get(i); - GroupUsage groupUsage = usage.second; - final Integer count = groupToAppCount.get(groupUsage.getGroup().getName()); - if (count == null) { - groups.add(groupUsage.getGroup()); - groupToAppCount.put(groupUsage.getGroup().getName(), 1); - } else { - groupToAppCount.put(groupUsage.getGroup().getName(), count + 1); - } - } - - groups.sort((x, y) -> { - final int usageDiff = compareLong(groupToAppCount.get(x.getName()), - groupToAppCount.get(y.getName())); - if (usageDiff != 0) { - return usageDiff; - } - // Make sure we lose no data if same - return y.hashCode() - x.hashCode(); - }); - - int numBarsToShow = Math.min(groups.size(), MAXIMUM_NUM_BARS); - for (int i = 0; i < numBarsToShow; i++) { - final AppPermissionGroup group = groups.get(i); - final Drawable icon = Utils.loadDrawable(context.getPackageManager(), - group.getIconPkg(), group.getIconResId()); - BarViewInfo barViewInfo = new BarViewInfo( - Utils.applyTint(context, icon, android.R.attr.colorControlNormal), - // The cast should not be a prob in practice - groupToAppCount.get(group.getName()), - R.string.app_permission_usage_bar_label, group.getLabel()); - - barViewInfo.setClickListener(v -> { - mFilterGroup = group.getName(); - // We already loaded all data, so don't reload - updateUI(); - }); - builder.addBarViewInfo(barViewInfo); - } - barChart.initializeBarChart(builder.build()); - return barChart; - } - /** * Create an expandable preference group that can hold children. * @@ -656,51 +624,42 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements pref.setTitleIcons(Collections.singletonList(group.getIconResId())); pref.setKey(group.getApp().packageName + "," + group.getName()); pref.useSmallerIcon(); + pref.setRightIcon(context.getDrawable(R.drawable.ic_settings)); return pref; } /** - * Compare two usages by the number of apps that accessed each group. + * Compare two usages by whichever app was used most recently. If the two represent the same + * app, sort by which group was used most recently. * * Can be used as a {@link java.util.Comparator}. * - * We ignore the GroupUsage here to ensure that we keep all usages by the same app together. - * * @param x a usage. * @param y a usage. * * @return see {@link java.util.Comparator#compare(Object, Object)}. */ - private static int compareAccessUsage(@NonNull Pair x, + private static int compareAccessAppRecency(@NonNull Pair x, @NonNull Pair y) { - final int groupDiff = getAccessedGroupCount(y.first) - getAccessedGroupCount(x.first); - if (groupDiff != 0) { - return groupDiff; + if (x.first.getApp().getKey().equals(y.first.getApp().getKey())) { + return compareAccessTime(x.second, y.second); } return compareAccessTime(x.first, y.first); } /** - * Gets the number of permission groups that have been accessed by the given app. + * Compare two usages by their access time. + * + * Can be used as a {@link java.util.Comparator}. * - * @param appPermissionUsage The app permission usage. - * @return The access count. + * @param x a usage. + * @param y a usage. + * + * @return see {@link java.util.Comparator#compare(Object, Object)}. */ - private static int getAccessedGroupCount(@NonNull AppPermissionUsage appPermissionUsage) { - int accessedCount = 0; - final List groupUsages = appPermissionUsage.getGroupUsages(); - final int groupCount = groupUsages.size(); - for (int i = 0; i < groupCount; i++) { - final GroupUsage groupUsage = groupUsages.get(i); - // STOPSHIP: Ignore {READ,WRITE}_EXTERNAL_STORAGE since they're going away. - if (groupUsage.getGroup().getLabel().equals("Storage")) { - continue; - } - if (groupUsage.getAccessCount() > 0) { - accessedCount++; - } - } - return accessedCount; + private static int compareAccessTime(@NonNull Pair x, + @NonNull Pair y) { + return compareAccessTime(x.second, y.second); } /** @@ -713,10 +672,8 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements * * @return see {@link java.util.Comparator#compare(Object, Object)}. */ - private static int compareAccessTime(@NonNull Pair x, - @NonNull Pair y) { - final int timeDiff = compareLong(x.second.getLastAccessTime(), - y.second.getLastAccessTime()); + private static int compareAccessTime(@NonNull GroupUsage x, @NonNull GroupUsage y) { + final int timeDiff = compareLong(x.getLastAccessTime(), y.getLastAccessTime()); if (timeDiff != 0) { return timeDiff; } @@ -779,10 +736,6 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements if (timeDiff != 0) { return timeDiff; } - final int countDiff = compareAccessUsage(x, y); - if (countDiff != 0) { - return countDiff; - } // Make sure we lose no data if same return x.hashCode() - y.hashCode(); } -- GitLab From 128a0876d4b9d016a09af62d99e5771876b53c77 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Wed, 20 Mar 2019 12:17:55 -0700 Subject: [PATCH 461/701] Pass a String to RuntimePermissionUsageInfo for the group name. Fixes: 128994612 Test: Call API. Change-Id: I10405e229db6bce97e9b1a58a21c42f5e6994517 --- .../service/PermissionControllerServiceImpl.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java b/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java index eb4e85436..0178bca88 100644 --- a/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java +++ b/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java @@ -441,7 +441,7 @@ public final class PermissionControllerServiceImpl extends PermissionControllerS @Override public @NonNull List onGetPermissionUsages( boolean countSystem, long numMillis) { - ArrayMap groupUsers = new ArrayMap<>(); + ArrayMap groupUsers = new ArrayMap<>(); long curTime = System.currentTimeMillis(); PermissionUsages usages = new PermissionUsages(this); @@ -474,12 +474,12 @@ public final class PermissionControllerServiceImpl extends PermissionControllerS continue; } - CharSequence groupLabel = groupUsage.getGroup().getName(); - Integer numUsers = groupUsers.get(groupLabel); + String groupName = groupUsage.getGroup().getName(); + Integer numUsers = groupUsers.get(groupName); if (numUsers == null) { - groupUsers.put(groupLabel, 1); + groupUsers.put(groupName, 1); } else { - groupUsers.put(groupLabel, numUsers + 1); + groupUsers.put(groupName, numUsers + 1); } } } -- GitLab From a12c09791cf94c705df23ea813378e7c0e47acff Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Sat, 9 Mar 2019 14:14:34 -0800 Subject: [PATCH 462/701] Implement dual storage permission model ... and remove old special handling of storage permissions. Test: - Looked at UI with apps in different quadrats of the storage permission model - Tried to revoke permssion of grandfathered Q app Bug: 126785920 Change-Id: I1ed80a4d1f681820711796cf2265615261491892 --- res/drawable/ic_warning.xml | 25 ++++++ res/layout/dialog_header.xml | 27 ++++++ res/values/overlayable.xml | 8 ++ res/values/strings.xml | 10 +++ res/values/styles.xml | 28 +++++++ .../permission/model/AppPermissionGroup.java | 83 +++++++------------ .../ui/handheld/AppPermissionFragment.java | 54 +++++++++++- .../handheld/AppPermissionUsageFragment.java | 4 - .../ui/handheld/AppPermissionsFragment.java | 3 +- .../ui/handheld/PermissionAppsFragment.java | 3 +- .../ui/handheld/PermissionUsageFragment.java | 4 - 11 files changed, 183 insertions(+), 66 deletions(-) create mode 100644 res/drawable/ic_warning.xml create mode 100644 res/layout/dialog_header.xml diff --git a/res/drawable/ic_warning.xml b/res/drawable/ic_warning.xml new file mode 100644 index 000000000..e09331c29 --- /dev/null +++ b/res/drawable/ic_warning.xml @@ -0,0 +1,25 @@ + + + + + \ No newline at end of file diff --git a/res/layout/dialog_header.xml b/res/layout/dialog_header.xml new file mode 100644 index 000000000..0123a05e8 --- /dev/null +++ b/res/layout/dialog_header.xml @@ -0,0 +1,27 @@ + + + + + + + + + diff --git a/res/values/overlayable.xml b/res/values/overlayable.xml index cd6ecaddf..3a28b913b 100644 --- a/res/values/overlayable.xml +++ b/res/values/overlayable.xml @@ -91,6 +91,14 @@ + + + + + + + + diff --git a/res/values/strings.xml b/res/values/strings.xml index 34dec0145..57d37d8fd 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -626,4 +626,14 @@ Allow %4$s to upload a bug repo Deny + + + Uninstall the app as permission can\u2019t be denied + + + %1$s has legacy storage permission to keep your previous data accessible.\n\nYou need to uninstall this app and reinstall it, as the app can stop working if this permission is denied. + + + Got it diff --git a/res/values/styles.xml b/res/values/styles.xml index 9db9dde5a..7e2f27175 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -382,4 +382,32 @@ + + + + + + + + + + diff --git a/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java b/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java index 1f2d110f5..0dac2b956 100644 --- a/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java +++ b/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java @@ -18,14 +18,11 @@ package com.android.packageinstaller.permission.model; import static android.Manifest.permission.ACCESS_BACKGROUND_LOCATION; import static android.Manifest.permission.ACCESS_FINE_LOCATION; -import static android.Manifest.permission.READ_EXTERNAL_STORAGE; -import static android.Manifest.permission.READ_MEDIA_AUDIO; -import static android.Manifest.permission.READ_MEDIA_IMAGES; -import static android.Manifest.permission.READ_MEDIA_VIDEO; -import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE; import static android.app.AppOpsManager.MODE_ALLOWED; import static android.app.AppOpsManager.MODE_FOREGROUND; import static android.app.AppOpsManager.MODE_IGNORED; +import static android.app.AppOpsManager.OPSTR_LEGACY_STORAGE; +import static android.content.pm.PackageManager.FLAG_PERMISSION_HIDDEN; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import android.app.ActivityManager; @@ -39,7 +36,6 @@ import android.content.pm.PermissionGroupInfo; import android.content.pm.PermissionInfo; import android.os.Build; import android.os.UserHandle; -import android.os.storage.StorageManager; import android.permission.PermissionManager; import android.provider.Settings; import android.text.TextUtils; @@ -110,6 +106,7 @@ public final class AppPermissionGroup implements Comparable private final boolean mAppSupportsRuntimePermissions; private final boolean mIsEphemeralApp; + private final boolean mIsGrandfatheredModernStorageGroup; private boolean mContainsEphemeralPermission; private boolean mContainsPreRuntimePermission; @@ -309,6 +306,10 @@ public final class AppPermissionGroup implements Comparable for (int i = 0; i < numPermissions; i++) { Permission permission = allPermissions.valueAt(i); + if ((permission.getFlags() & FLAG_PERMISSION_HIDDEN) != 0) { + continue; + } + if (permission.isBackgroundPermission()) { if (group.getBackgroundPermissions() == null) { group.mBackgroundPermissions = new AppPermissionGroup(group.mContext, @@ -339,6 +340,10 @@ public final class AppPermissionGroup implements Comparable } } + if (group.getPermissions().isEmpty()) { + return null; + } + return group; } @@ -375,12 +380,13 @@ public final class AppPermissionGroup implements Comparable @StringRes int backgroundRequest, @StringRes int backgroundRequestDetail, String iconPkg, int iconResId, UserHandle userHandle, boolean delayChanges) { + int targetSDK = packageInfo.applicationInfo.targetSdkVersion; + mContext = context; mUserHandle = userHandle; mPackageManager = mContext.getPackageManager(); mPackageInfo = packageInfo; - mAppSupportsRuntimePermissions = packageInfo.applicationInfo - .targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1; + mAppSupportsRuntimePermissions = targetSDK > Build.VERSION_CODES.LOLLIPOP_MR1; mIsEphemeralApp = packageInfo.applicationInfo.isInstantApp(); mAppOps = context.getSystemService(AppOpsManager.class); mActivityManager = context.getSystemService(ActivityManager.class); @@ -403,6 +409,10 @@ public final class AppPermissionGroup implements Comparable mIconPkg = context.getPackageName(); mIconResId = R.drawable.ic_perm_device_info; } + + mIsGrandfatheredModernStorageGroup = targetSDK >= Build.VERSION_CODES.Q + && mAppOps.unsafeCheckOpNoThrow(OPSTR_LEGACY_STORAGE, + packageInfo.applicationInfo.uid, packageInfo.packageName) == MODE_ALLOWED; } public boolean doesSupportRuntimePermissions() { @@ -1054,6 +1064,18 @@ public final class AppPermissionGroup implements Comparable return mHasPermissionWithBackgroundMode; } + /** + * Is the group a grandfathered modern storage permission group. + * + *

Such permissions cannot be revoked. The user needs to uninstall and reinstall the app to + * reset the permission + * + * @return {@code true} iff this is a grandfathered modern storage permission group. + */ + public boolean isGrandfatheredModernStorageGroup() { + return mIsGrandfatheredModernStorageGroup; + } + /** * Whether this is group that contains all the background permission for regular permission * group. @@ -1186,7 +1208,6 @@ public final class AppPermissionGroup implements Comparable int numPermissions = mPermissions.size(); boolean shouldKillApp = false; - boolean shouldUpdateStorage = false; for (int i = 0; i < numPermissions; i++) { Permission permission = mPermissions.valueAt(i); @@ -1235,50 +1256,6 @@ public final class AppPermissionGroup implements Comparable } } } - - switch (permission.getName()) { - case READ_MEDIA_AUDIO: - case READ_MEDIA_VIDEO: - case READ_MEDIA_IMAGES: - shouldUpdateStorage = true; - break; - } - } - - // Starting in Q, the legacy "Storage" permission has been split into - // new strongly-typed runtime permissions. When older apps request - // the "Storage" permission, we already translate that into requests for - // the new split permissions, but those older apps may be confused if - // the legacy permission isn't actually granted. Thus, as a special - // case, whenever any of the new split permissions are granted to an - // app, we also grant them the legacy "Storage" permission. - if (StorageManager.hasIsolatedStorage() && shouldUpdateStorage) { - boolean audioGranted = mContext.checkPermission(READ_MEDIA_AUDIO, - -1, uid) == PERMISSION_GRANTED; - boolean videoGranted = mContext.checkPermission(READ_MEDIA_VIDEO, - -1, uid) == PERMISSION_GRANTED; - boolean imagesGranted = mContext.checkPermission(READ_MEDIA_IMAGES, - -1, uid) == PERMISSION_GRANTED; - - if (!ArrayUtils.isEmpty(mPackageInfo.requestedPermissions)) { - for (String permission : mPackageInfo.requestedPermissions) { - if (READ_EXTERNAL_STORAGE.equals(permission) - || WRITE_EXTERNAL_STORAGE.equals(permission)) { - if (audioGranted || videoGranted || imagesGranted) { - mPackageManager.grantRuntimePermission(mPackageInfo.packageName, - permission, mUserHandle); - } else { - boolean isCurrentlyGranted = mContext.checkPermission(permission, -1, - uid) == PERMISSION_GRANTED; - - if (isCurrentlyGranted) { - mPackageManager.revokeRuntimePermission(mPackageInfo.packageName, - permission, mUserHandle); - } - } - } - } - } } if (mayKillBecauseOfAppOpsChange && shouldKillApp) { diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java index 2f8794f56..d909ab4ce 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java @@ -367,7 +367,13 @@ public class AppPermissionFragment extends SettingsWithLargeHeader { } // Handle the UI for various special cases. - if (isSystemFixed() || isPolicyFullyFixed() || isForegroundDisabledByPolicy()) { + if (mGroup.isGrandfatheredModernStorageGroup()) { + mAlwaysButton.setClickable(false); + mDenyButton.setClickable(false); + + mRadioGroup.setClickable(true); + mRadioGroup.setOnClickListener(v -> showGrandfatheredModernStorageGroupWarningDialog()); + } else if (isSystemFixed() || isPolicyFullyFixed() || isForegroundDisabledByPolicy()) { // Disable changing permissions and potentially show administrator message. mAlwaysButton.setEnabled(false); mForegroundOnlyButton.setEnabled(false); @@ -808,6 +814,19 @@ public class AppPermissionFragment extends SettingsWithLargeHeader { DefaultDenyDialog.class.getName()); } + private void showGrandfatheredModernStorageGroupWarningDialog() { + Bundle args = new Bundle(); + args.putParcelable(GrandfatheredModernStorageGroupWarningDialog.APP_INFO, + mGroup.getApp().applicationInfo); + + GrandfatheredModernStorageGroupWarningDialog warningDialog = + new GrandfatheredModernStorageGroupWarningDialog(); + warningDialog.setArguments(args); + warningDialog.setTargetFragment(this, 0); + warningDialog.show(getFragmentManager().beginTransaction(), + GrandfatheredModernStorageGroupWarningDialog.class.getName()); + } + /** * Once we user has confirmed that he/she wants to revoke a permission that was granted by * default, actually revoke the permissions. @@ -844,6 +863,39 @@ public class AppPermissionFragment extends SettingsWithLargeHeader { updateButtons(); } + /** + * A dialog warning the user that she/he is about to deny a permission that was granted by + * default. + * + * @see #showGrandfatheredModernStorageGroupWarningDialog() + */ + public static class GrandfatheredModernStorageGroupWarningDialog extends DialogFragment { + private static final String APP_INFO = + GrandfatheredModernStorageGroupWarningDialog.class.getName() + ".arg.appInfo"; + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + Context context = getContext(); + + ApplicationInfo appInfo = getArguments().getParcelable(APP_INFO); + + View header = LayoutInflater.from(context).inflate(R.layout.dialog_header, null); + ((ImageView) header.requireViewById(R.id.icon)).setImageDrawable( + context.getDrawable(R.drawable.ic_warning)); + ((TextView) header.requireViewById(R.id.title)).setText( + R.string.grandfathered_modern_storage_permission_deny_warning_title); + + AlertDialog.Builder b = new AlertDialog.Builder(context) + .setCustomTitle(header) + .setMessage(context.getString( + R.string.grandfathered_modern_storage_permission_deny_warning_content, + Utils.getFullAppLabel(appInfo, context))) + .setPositiveButton(R.string.dismiss_with_acknowledgment, null); + + return b.create(); + } + } + /** * A dialog warning the user that she/he is about to deny a permission that was granted by * default. diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java index 923b6f901..b6a976e05 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java @@ -242,10 +242,6 @@ public class AppPermissionUsageFragment extends SettingsWithLargeHeader implemen continue; } final AppPermissionGroup group = groupUsage.getGroup(); - // STOPSHIP: Ignore {READ,WRITE}_EXTERNAL_STORAGE since they're going away. - if (group.getLabel().equals("Storage")) { - continue; - } PermissionControlPreference pref = new PermissionControlPreference(context, group); pref.setTitle(groupUsage.getGroup().getLabel()); pref.setUsageSummary(groupUsage, Utils.getAbsoluteLastUsageString(context, groupUsage)); diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java index bb7eff790..550bdaa06 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java @@ -233,8 +233,7 @@ public final class AppPermissionsFragment extends SettingsWithLargeHeader { if (Utils.isModernPermissionGroup(group.getName())) { String lastAccessStr = Utils.getAbsoluteLastUsageString(context, PermissionUsages.loadLastGroupUsage(context, group)); - // STOPSHIP: Ignore {READ,WRITE}_EXTERNAL_STORAGE since they're going away. - if (lastAccessStr != null && !group.getLabel().equals("Storage")) { + if (lastAccessStr != null) { preference.setSummary( context.getString(R.string.app_permission_most_recent_summary, lastAccessStr)); diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java index 0b667163b..5d9a6b0ee 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java @@ -372,8 +372,7 @@ public final class PermissionAppsFragment extends SettingsWithLargeHeader implem } String lastAccessStr = Utils.getAbsoluteLastUsageString(context, PermissionUsages.loadLastGroupUsage(context, group)); - // STOPSHIP: Ignore {READ,WRITE}_EXTERNAL_STORAGE since they're going away. - if (lastAccessStr != null && !group.getLabel().equals("Storage")) { + if (lastAccessStr != null) { pref.setSummary(context.getString(R.string.app_permission_most_recent_summary, lastAccessStr)); } else if (Utils.isPermissionsHubEnabled()) { diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java index b975fb7e5..620294a55 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java @@ -422,10 +422,6 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements if (isSystemApp && !mShowSystem) { continue; } - // STOPSHIP: Ignore {READ,WRITE}_EXTERNAL_STORAGE since they're going away. - if (groupUsage.getGroup().getLabel().equals("Storage")) { - continue; - } usages.add(Pair.create(appUsage, appGroups.get(groupNum))); used = true; -- GitLab From 31c58cbb61a8df6df295c9aadbf0317315596691 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Thu, 14 Mar 2019 16:48:36 -0700 Subject: [PATCH 463/701] Migrate the ongoing usage dialog from SysUI. Fixes: 128690096 Test: Open dialog with various apps/permissions in use. Change-Id: I55c39795ea4787e751da2ef3ae6db8398e15acf0 --- AndroidManifest.xml | 10 + res/layout/ongoing_usage_dialog_content.xml | 45 ++++ res/layout/ongoing_usage_dialog_item.xml | 38 +++ res/values/overlayable.xml | 13 ++ res/values/strings.xml | 15 ++ res/values/styles.xml | 79 +++++++ .../permission/model/AppPermissionUsage.java | 21 ++ .../ui/ReviewOngoingUsageActivity.java | 216 ++++++++++++++++++ 8 files changed, 437 insertions(+) create mode 100644 res/layout/ongoing_usage_dialog_content.xml create mode 100644 res/layout/ongoing_usage_dialog_item.xml create mode 100644 src/com/android/packageinstaller/permission/ui/ReviewOngoingUsageActivity.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 9914e344e..199a2d119 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -141,6 +141,16 @@ android:excludeFromRecents="true" android:theme="@android:style/Theme.DeviceDefault.Light.Dialog.NoActionBar" /> + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/layout/ongoing_usage_dialog_item.xml b/res/layout/ongoing_usage_dialog_item.xml new file mode 100644 index 000000000..08fbf277c --- /dev/null +++ b/res/layout/ongoing_usage_dialog_item.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + diff --git a/res/values/overlayable.xml b/res/values/overlayable.xml index 3a28b913b..2172f58bc 100644 --- a/res/values/overlayable.xml +++ b/res/values/overlayable.xml @@ -99,6 +99,19 @@ + + + + + + + + + + + + + diff --git a/res/values/strings.xml b/res/values/strings.xml index 57d37d8fd..4fd64126c 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -526,6 +526,21 @@ default apps + + Got it + + + Privacy settings + + + Apps using your %s + + + ,\u0020 + + + \u0020and\u0020 + Default apps diff --git a/res/values/styles.xml b/res/values/styles.xml index 7e2f27175..16198d029 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -410,4 +410,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/com/android/packageinstaller/permission/model/AppPermissionUsage.java b/src/com/android/packageinstaller/permission/model/AppPermissionUsage.java index f1b742d56..6a54d5831 100644 --- a/src/com/android/packageinstaller/permission/model/AppPermissionUsage.java +++ b/src/com/android/packageinstaller/permission/model/AppPermissionUsage.java @@ -162,6 +162,27 @@ public final class AppPermissionUsage { ); } + public boolean isRunning() { + if (mLastUsage == null) { + return false; + } + final ArrayList permissions = mGroup.getPermissions(); + final int permissionCount = permissions.size(); + for (int i = 0; i < permissionCount; i++) { + final Permission permission = permissions.get(i); + final String opName = permission.getAppOp(); + final List ops = mLastUsage.getOps(); + final int opCount = ops.size(); + for (int j = 0; j < opCount; j++) { + final OpEntry op = ops.get(j); + if (op.getOpStr().equals(opName) && op.isRunning()) { + return true; + } + } + } + return false; + } + private long extractAggregate(@NonNull Function extractor) { long aggregate = 0; final ArrayList permissions = mGroup.getPermissions(); diff --git a/src/com/android/packageinstaller/permission/ui/ReviewOngoingUsageActivity.java b/src/com/android/packageinstaller/permission/ui/ReviewOngoingUsageActivity.java new file mode 100644 index 000000000..9801e5da3 --- /dev/null +++ b/src/com/android/packageinstaller/permission/ui/ReviewOngoingUsageActivity.java @@ -0,0 +1,216 @@ +/* + * Copyright (C) 2019 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.packageinstaller.permission.ui; + +import static android.Manifest.permission_group.CAMERA; +import static android.Manifest.permission_group.LOCATION; +import static android.Manifest.permission_group.MICROPHONE; + +import android.app.AlertDialog; +import android.content.Intent; +import android.os.Bundle; +import android.os.UserHandle; +import android.provider.Settings; +import android.util.ArraySet; +import android.util.Pair; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentActivity; + +import com.android.packageinstaller.permission.model.AppPermissionUsage; +import com.android.packageinstaller.permission.model.AppPermissionUsage.GroupUsage; +import com.android.packageinstaller.permission.model.PermissionApps; +import com.android.packageinstaller.permission.model.PermissionApps.PermissionApp; +import com.android.packageinstaller.permission.model.PermissionUsages; +import com.android.packageinstaller.permission.utils.Utils; +import com.android.permissioncontroller.R; + +import java.text.Collator; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * A dialog listing the currently uses of camera, microphone, and location. + */ +public final class ReviewOngoingUsageActivity extends FragmentActivity { + + // Number of milliseconds in the past to look for accesses if nothing was specified. + private static final long DEFAULT_MILLIS = 5000; + + private @NonNull PermissionUsages mPermissionUsages; + private @Nullable AlertDialog mDialog; + private long mStartTime; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + if (!Utils.isPermissionsHubEnabled()) { + return; + } + + long numMillis = getIntent().getLongExtra(Intent.EXTRA_DURATION_MILLIS, DEFAULT_MILLIS); + + mPermissionUsages = new PermissionUsages(this); + mStartTime = Math.max(System.currentTimeMillis() - numMillis, Instant.EPOCH.toEpochMilli()); + mPermissionUsages.load(null, null, mStartTime, Long.MAX_VALUE, + PermissionUsages.USAGE_FLAG_LAST, getLoaderManager(), false, false, + this::onPermissionUsagesLoaded, false); + } + + private void onPermissionUsagesLoaded() { + List appPermissionUsages = mPermissionUsages.getUsages(); + + List>> usages = new ArrayList<>(); + ArrayList permApps = new ArrayList<>(); + int numApps = appPermissionUsages.size(); + for (int appNum = 0; appNum < numApps; appNum++) { + AppPermissionUsage appUsage = appPermissionUsages.get(appNum); + + List usedGroups = new ArrayList<>(); + List appGroups = appUsage.getGroupUsages(); + int numGroups = appGroups.size(); + for (int groupNum = 0; groupNum < numGroups; groupNum++) { + GroupUsage groupUsage = appGroups.get(groupNum); + String groupName = groupUsage.getGroup().getName(); + + if (groupUsage.getLastAccessTime() < mStartTime && !groupUsage.isRunning()) { + continue; + } + if (!groupName.equals(CAMERA) && !groupName.equals(LOCATION) && !groupName.equals( + MICROPHONE)) { + continue; + } + if (!Utils.isGroupOrBgGroupUserSensitive(groupUsage.getGroup())) { + continue; + } + + usedGroups.add(appGroups.get(groupNum)); + } + + if (!usedGroups.isEmpty()) { + usages.add(Pair.create(appUsage, usedGroups)); + permApps.add(appUsage.getApp()); + } + } + + if (usages.isEmpty()) { + finish(); + return; + } + + new PermissionApps.AppDataLoader(this, () -> showDialog(usages)) + .execute(permApps.toArray(new PermissionApps.PermissionApp[permApps.size()])); + } + + private void showDialog(@NonNull List>> usages) { + mDialog = new AlertDialog.Builder(this) + .setView(createDialogView(usages)) + .setPositiveButton(R.string.ongoing_usage_dialog_ok, null) + .setNeutralButton(R.string.ongoing_usage_dialog_open_settings, (dialog, which) -> + startActivity(new Intent(Settings.ACTION_PRIVACY_SETTINGS).putExtra( + Intent.EXTRA_DURATION_MILLIS, TimeUnit.MINUTES.toMillis(1)))) + .setOnDismissListener((dialog) -> finish()) + .create(); + mDialog.show(); + } + + private @NonNull View createDialogView( + @NonNull List>> usages) { + LayoutInflater inflater = LayoutInflater.from(this); + View contentView = inflater.inflate(R.layout.ongoing_usage_dialog_content, null); + ViewGroup appsList = contentView.requireViewById(R.id.items_container); + + // Compute all of the permission group labels that were used. + ArraySet usedGroups = new ArraySet<>(); + int numUsages = usages.size(); + for (int usageNum = 0; usageNum < numUsages; usageNum++) { + List groups = usages.get(usageNum).second; + int numGroups = groups.size(); + for (int groupNum = 0; groupNum < numGroups; groupNum++) { + usedGroups.add(groups.get(groupNum).getGroup().getLabel().toString().toLowerCase()); + } + } + + // Add the layout for each app. + for (int usageNum = 0; usageNum < numUsages; usageNum++) { + Pair> usage = usages.get(usageNum); + PermissionApp app = usage.first.getApp(); + List groups = usage.second; + + View itemView = inflater.inflate(R.layout.ongoing_usage_dialog_item, appsList, false); + + ((TextView) itemView.requireViewById(R.id.app_name)).setText(app.getLabel()); + ((ImageView) itemView.requireViewById(R.id.app_icon)).setImageDrawable(app.getIcon()); + + // Add the icons for the groups this app used as long as multiple groups were used by + // some app. + if (usedGroups.size() > 1) { + ViewGroup iconFrame = itemView.requireViewById(R.id.icons); + int numGroups = usages.get(usageNum).second.size(); + for (int groupNum = 0; groupNum < numGroups; groupNum++) { + ViewGroup group = (ViewGroup) inflater.inflate(R.layout.image_view, null); + ((ImageView) group.requireViewById(R.id.icon)).setImageDrawable( + Utils.applyTint(this, groups.get(groupNum).getGroup().getIconResId(), + android.R.attr.colorControlNormal)); + iconFrame.addView(group); + } + iconFrame.setVisibility(View.VISIBLE); + } + + itemView.setOnClickListener((v) -> { + Intent intent = new Intent(Intent.ACTION_MANAGE_APP_PERMISSIONS); + intent.putExtra(Intent.EXTRA_PACKAGE_NAME, app.getPackageName()); + intent.putExtra(Intent.EXTRA_USER, UserHandle.getUserHandleForUid(app.getUid())); + startActivity(intent); + mDialog.dismiss(); + }); + + appsList.addView(itemView); + } + + // Set the title of the dialog based on all of the permissions used. + StringBuilder titleBuilder = new StringBuilder(); + int numGroups = usedGroups.size(); + List sortedGroups = new ArrayList<>(usedGroups); + Collator collator = Collator.getInstance( + getResources().getConfiguration().getLocales().get(0)); + sortedGroups.sort(collator); + for (int i = 0; i < numGroups; i++) { + titleBuilder.append(sortedGroups.get(i)); + if (i < numGroups - 2) { + titleBuilder.append(getString(R.string.ongoing_usage_dialog_separator)); + } else if (i < numGroups - 1) { + titleBuilder.append(getString(R.string.ongoing_usage_dialog_last_separator)); + } + } + + ((TextView) contentView.requireViewById(R.id.title)).setText( + getString(R.string.ongoing_usage_dialog_title, titleBuilder.toString())); + + return contentView; + } + +} -- GitLab From 7fd46c5c0fd8a4b0960cbdd6d1c12ecde0ed6bf7 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Wed, 20 Mar 2019 08:49:46 -0700 Subject: [PATCH 464/701] Allow loading only a subset of permission groups. This speeds up the ongoing usage dialog, which only needs three permission groups. Test: Open ongoing usage dialog and Permissions Hub. Change-Id: I5b62cc834b8ac39194e8080d1107b0079d1ebfd8 --- .../permission/model/PermissionGroups.java | 20 +++++++++-------- .../permission/model/PermissionUsages.java | 22 +++++++++---------- .../ui/ReviewOngoingUsageActivity.java | 8 ++----- .../ui/handheld/PermissionUsageFragment.java | 2 +- 4 files changed, 25 insertions(+), 27 deletions(-) diff --git a/src/com/android/packageinstaller/permission/model/PermissionGroups.java b/src/com/android/packageinstaller/permission/model/PermissionGroups.java index 26d68a416..eb7e4540b 100644 --- a/src/com/android/packageinstaller/permission/model/PermissionGroups.java +++ b/src/com/android/packageinstaller/permission/model/PermissionGroups.java @@ -156,14 +156,14 @@ public final class PermissionGroups implements LoaderCallbacks getPermissionGroups(@NonNull Context context, @Nullable Supplier isCanceled, boolean getAppUiInfo, - boolean getNonPlatformPermissions, @Nullable String groupName, + boolean getNonPlatformPermissions, @Nullable String[] groupNames, @Nullable String packageName) { PermissionApps.PmCache pmCache = new PermissionApps.PmCache( context.getPackageManager()); @@ -174,7 +174,7 @@ public final class PermissionGroups implements LoaderCallbacks seenPermissions = new ArraySet<>(); PackageManager packageManager = context.getPackageManager(); - List groupInfos = getPermissionGroupInfos(context, groupName); + List groupInfos = getPermissionGroupInfos(context, groupNames); for (PermissionGroupInfo groupInfo : groupInfos) { // Mare sure we respond to cancellation. @@ -303,15 +303,17 @@ public final class PermissionGroups implements LoaderCallbacks getPermissionGroupInfos( - @NonNull Context context, @Nullable String groupName) { - if (groupName == null) { + @NonNull Context context, @Nullable String[] groupNames) { + if (groupNames == null) { return context.getPackageManager().getAllPermissionGroups(0); } try { - final PermissionGroupInfo groupInfo = context.getPackageManager() - .getPermissionGroupInfo(groupName, 0); - final List groupInfos = new ArrayList<>(1); - groupInfos.add(groupInfo); + final List groupInfos = new ArrayList<>(groupNames.length); + for (int i = 0; i < groupNames.length; i++) { + final PermissionGroupInfo groupInfo = context.getPackageManager() + .getPermissionGroupInfo(groupNames[i], 0); + groupInfos.add(groupInfo); + } return groupInfos; } catch (PackageManager.NameNotFoundException e) { return Collections.emptyList(); diff --git a/src/com/android/packageinstaller/permission/model/PermissionUsages.java b/src/com/android/packageinstaller/permission/model/PermissionUsages.java index 71248392b..fde235790 100644 --- a/src/com/android/packageinstaller/permission/model/PermissionUsages.java +++ b/src/com/android/packageinstaller/permission/model/PermissionUsages.java @@ -77,18 +77,18 @@ public final class PermissionUsages implements LoaderCallbacks> { private final int mFilterUid; private @Nullable String mFilterPackageName; - private @Nullable String mFilterPermissionGroup; + private @Nullable String[] mFilterPermissionGroups; private final long mFilterBeginTimeMillis; private final long mFilterEndTimeMillis; private final int mUsageFlags; @@ -175,7 +175,7 @@ public final class PermissionUsages implements LoaderCallbacks loadInBackground() { final List groups = PermissionGroups.getPermissionGroups( getContext(), this::isLoadInBackgroundCanceled, mGetUiInfo, - mGetNonPlatformPermissions, mFilterPermissionGroup, mFilterPackageName); + mGetNonPlatformPermissions, mFilterPermissionGroups, mFilterPackageName); if (!Utils.isPermissionsHubEnabled()) { return Collections.emptyList(); } diff --git a/src/com/android/packageinstaller/permission/ui/ReviewOngoingUsageActivity.java b/src/com/android/packageinstaller/permission/ui/ReviewOngoingUsageActivity.java index 9801e5da3..3486d8492 100644 --- a/src/com/android/packageinstaller/permission/ui/ReviewOngoingUsageActivity.java +++ b/src/com/android/packageinstaller/permission/ui/ReviewOngoingUsageActivity.java @@ -75,8 +75,8 @@ public final class ReviewOngoingUsageActivity extends FragmentActivity { mPermissionUsages = new PermissionUsages(this); mStartTime = Math.max(System.currentTimeMillis() - numMillis, Instant.EPOCH.toEpochMilli()); - mPermissionUsages.load(null, null, mStartTime, Long.MAX_VALUE, - PermissionUsages.USAGE_FLAG_LAST, getLoaderManager(), false, false, + mPermissionUsages.load(null, new String[] { CAMERA, LOCATION, MICROPHONE }, mStartTime, + Long.MAX_VALUE, PermissionUsages.USAGE_FLAG_LAST, getLoaderManager(), false, false, this::onPermissionUsagesLoaded, false); } @@ -99,10 +99,6 @@ public final class ReviewOngoingUsageActivity extends FragmentActivity { if (groupUsage.getLastAccessTime() < mStartTime && !groupUsage.isRunning()) { continue; } - if (!groupName.equals(CAMERA) && !groupName.equals(LOCATION) && !groupName.equals( - MICROPHONE)) { - continue; - } if (!Utils.isGroupOrBgGroupUserSensitive(groupUsage.getGroup())) { continue; } diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java index 620294a55..cfc23bcdf 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java @@ -569,7 +569,7 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements } final long filterTimeBeginMillis = Math.max(System.currentTimeMillis() - timeFilterItem.getTime(), Instant.EPOCH.toEpochMilli()); - mPermissionUsages.load(null /*filterPackageName*/, null /*filterPermissionGroup*/, + mPermissionUsages.load(null /*filterPackageName*/, null /*filterPermissionGroups*/, filterTimeBeginMillis, Long.MAX_VALUE, PermissionUsages.USAGE_FLAG_LAST | PermissionUsages.USAGE_FLAG_HISTORICAL, getActivity().getLoaderManager(), false /*getUiInfo*/, false /*getNonPlatformPermissions*/, this /*callback*/, -- GitLab From de56060f34dc623358ddfede544e4aebb9099439 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Wed, 20 Mar 2019 15:40:02 -0700 Subject: [PATCH 465/701] Remove AppPermissionUsageFragment. This is no longer used, so remove it and the link to it. Fixes: 129006895 Test: Click around on various UIs. Change-Id: I7acdbe37a8faf049d07de885475d6d2dffaa6ce4 --- AndroidManifest.xml | 1 - .../ui/ManagePermissionsActivity.java | 21 -- .../handheld/AppPermissionUsageFragment.java | 277 ------------------ .../ui/handheld/AppPermissionsFragment.java | 19 +- 4 files changed, 1 insertion(+), 317 deletions(-) delete mode 100644 src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 9914e344e..820bd6ac4 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -95,7 +95,6 @@ - diff --git a/src/com/android/packageinstaller/permission/ui/ManagePermissionsActivity.java b/src/com/android/packageinstaller/permission/ui/ManagePermissionsActivity.java index 564472a69..93c3b50a8 100644 --- a/src/com/android/packageinstaller/permission/ui/ManagePermissionsActivity.java +++ b/src/com/android/packageinstaller/permission/ui/ManagePermissionsActivity.java @@ -140,27 +140,6 @@ public final class ManagePermissionsActivity extends FragmentActivity { } } break; - case Intent.ACTION_REVIEW_APP_PERMISSION_USAGE: { - if (!Utils.isPermissionsHubEnabled()) { - return; - } - - String packageName = getIntent().getStringExtra(Intent.EXTRA_PACKAGE_NAME); - if (packageName == null) { - Log.i(LOG_TAG, "Missing mandatory argument EXTRA_PACKAGE_NAME"); - finish(); - return; - } - UserHandle userHandle = getIntent().getParcelableExtra(Intent.EXTRA_USER); - if (userHandle == null) { - Log.i(LOG_TAG, "Missing mandatory argument EXTRA_USER"); - finish(); - return; - } - androidXFragment = com.android.packageinstaller.permission.ui.handheld - .AppPermissionUsageFragment.newInstance(packageName, userHandle); - } break; - default: { Log.w(LOG_TAG, "Unrecognized action " + action); finish(); diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java deleted file mode 100644 index b6a976e05..000000000 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionUsageFragment.java +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.packageinstaller.permission.ui.handheld; - -import android.app.ActionBar; -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.graphics.drawable.Drawable; -import android.os.Bundle; -import android.os.UserHandle; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemSelectedListener; -import android.widget.Spinner; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.preference.PreferenceScreen; - -import com.android.packageinstaller.permission.model.AppPermissionGroup; -import com.android.packageinstaller.permission.model.AppPermissionUsage; -import com.android.packageinstaller.permission.model.AppPermissionUsage.GroupUsage; -import com.android.packageinstaller.permission.model.PermissionUsages; -import com.android.packageinstaller.permission.ui.handheld.FilterSpinner.FilterSpinnerAdapter; -import com.android.packageinstaller.permission.ui.handheld.FilterSpinner.TimeFilterItem; -import com.android.packageinstaller.permission.utils.Utils; -import com.android.permissioncontroller.R; - -import java.time.Instant; -import java.util.Comparator; -import java.util.List; - -/** - * Show the usage of all permission groups by a single app. - * - *

Shows a list of app usage of permission groups, each of which links to - * AppPermissionsFragment. - */ -public class AppPermissionUsageFragment extends SettingsWithLargeHeader implements - OnItemSelectedListener { - - private static final String LOG_TAG = "AppPermissionUsageFragment"; - - private static final String KEY_SPINNER_TIME_INDEX = "_time_index"; - private static final String SPINNER_TIME_INDEX_KEY = AppPermissionUsageFragment.class.getName() - + KEY_SPINNER_TIME_INDEX; - - private @NonNull String mPackageName; - private @NonNull ApplicationInfo mAppInfo; - - private @NonNull PermissionUsages mPermissionUsages; - - private Spinner mFilterSpinner; - private FilterSpinnerAdapter mFilterAdapter; - - /** - * Only used to restore spinner state after onCreate. Once the list of times is reported, this - * becomes invalid. - */ - private int mSavedSpinnerIndex; - - /** - * @return A new fragment - */ - public static @NonNull AppPermissionUsageFragment newInstance(@NonNull String packageName, - @NonNull UserHandle userHandle) { - AppPermissionUsageFragment fragment = new AppPermissionUsageFragment(); - Bundle arguments = new Bundle(); - arguments.putString(Intent.EXTRA_PACKAGE_NAME, packageName); - arguments.putParcelable(Intent.EXTRA_USER, userHandle); - fragment.setArguments(arguments); - return fragment; - } - - @Override - public void onStart() { - super.onStart(); - getActivity().setTitle(R.string.app_permission_usage_title); - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - if (savedInstanceState != null) { - mSavedSpinnerIndex = savedInstanceState.getInt(SPINNER_TIME_INDEX_KEY); - } - - setLoading(true, false); - setHasOptionsMenu(true); - ActionBar ab = getActivity().getActionBar(); - if (ab != null) { - ab.setDisplayHomeAsUpEnabled(true); - } - - mPackageName = getArguments().getString(Intent.EXTRA_PACKAGE_NAME); - UserHandle userHandle = getArguments().getParcelable(Intent.EXTRA_USER); - Activity activity = getActivity(); - mAppInfo = getApplicationInfo(getActivity(), mPackageName, userHandle); - if (mAppInfo == null) { - Toast.makeText(activity, R.string.app_not_found_dlg_title, Toast.LENGTH_LONG).show(); - activity.finish(); - return; - } - - mPermissionUsages = new PermissionUsages(getContext()); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - Context context = getPreferenceManager().getContext(); - ViewGroup root = (ViewGroup) super.onCreateView(inflater, container, savedInstanceState); - - View spinnerView = inflater.inflate(R.layout.single_spinner, root, false); - getPreferencesContainer().addView(spinnerView, 1); - - mFilterSpinner = spinnerView.requireViewById(R.id.filter_spinner); - mFilterAdapter = new FilterSpinnerAdapter<>(context); - mFilterSpinner.setAdapter(mFilterAdapter); - mFilterSpinner.setOnItemSelectedListener(this); - - FilterSpinner.addTimeFilters(mFilterAdapter, context); - mFilterSpinner.setSelection(mSavedSpinnerIndex); - - return root; - } - - @Override - public void onViewCreated(View view, Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - if (mAppInfo == null) { - return; - } - Drawable icon = Utils.getBadgedIcon(getActivity(), mAppInfo); - setHeader(icon, Utils.getFullAppLabel(mAppInfo, getContext()), null); - } - - @Override - public void onItemSelected(AdapterView parent, View view, int position, long id) { - reloadData(); - } - - @Override - public void onNothingSelected(AdapterView parent) { - } - - @Override - public void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - outState.putInt(SPINNER_TIME_INDEX_KEY, mFilterSpinner.getSelectedItemPosition()); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if (item.getItemId() == android.R.id.home) { - getActivity().finish(); - return true; - } - return super.onOptionsItemSelected(item); - } - - @Override - public int getEmptyViewString() { - return R.string.no_permission_usages; - } - - private static ApplicationInfo getApplicationInfo(@NonNull Activity activity, - @NonNull String packageName, @NonNull UserHandle userHandle) { - try { - return activity.createPackageContextAsUser(packageName, 0, - userHandle).getPackageManager().getApplicationInfo(packageName, 0); - } catch (PackageManager.NameNotFoundException e) { - Log.i(LOG_TAG, "No package: " + activity.getCallingPackage(), e); - return null; - } - } - - private void updateUi() { - if (!Utils.isPermissionsHubEnabled()) { - setLoading(false, true); - return; - } - Context context = getPreferenceManager().getContext(); - if (context == null) { - return; - } - - PreferenceScreen screen = getPreferenceScreen(); - if (screen == null) { - screen = getPreferenceManager().createPreferenceScreen(context); - setPreferenceScreen(screen); - } - screen.removeAll(); - - // Add the permission usages. - final List permissionUsages = mPermissionUsages.getUsages(); - if (permissionUsages.isEmpty()) { - setLoading(false, true); - return; - } - if (permissionUsages.size() > 1) { - Log.e(LOG_TAG, "Expected one AppPermissionUsage but got: " + permissionUsages); - getActivity().finish(); - return; - } - - // Get the current values of the time filter. - TimeFilterItem timeFilterItem = getSelectedFilterItem(); - long startTime = (timeFilterItem == null ? 0 - : (System.currentTimeMillis() - timeFilterItem.getTime())); - - final AppPermissionUsage appPermissionUsage = permissionUsages.get(0); - final List groupUsages = appPermissionUsage.getGroupUsages(); - groupUsages.sort(Comparator.comparing(GroupUsage::getLastAccessTime).reversed()); - - final int permissionCount = groupUsages.size(); - for (int permissionIdx = 0; permissionIdx < permissionCount; permissionIdx++) { - final GroupUsage groupUsage = groupUsages.get(permissionIdx); - if (groupUsage.getAccessCount() <= 0 || groupUsage.getLastAccessTime() < startTime) { - continue; - } - final AppPermissionGroup group = groupUsage.getGroup(); - PermissionControlPreference pref = new PermissionControlPreference(context, group); - pref.setTitle(groupUsage.getGroup().getLabel()); - pref.setUsageSummary(groupUsage, Utils.getAbsoluteLastUsageString(context, groupUsage)); - pref.setIcon(Utils.applyTint(context, group.getIconResId(), - android.R.attr.colorControlNormal)); - pref.setKey(group.getName()); - screen.addPreference(pref); - } - - setLoading(false, true); - } - - private TimeFilterItem getSelectedFilterItem() { - int pos = mFilterSpinner.getSelectedItemPosition(); - if (pos != AdapterView.INVALID_POSITION) { - return mFilterAdapter.getFilter(pos); - } - return null; - } - - private void reloadData() { - TimeFilterItem timeFilterItem = getSelectedFilterItem(); - if (timeFilterItem == null) { - return; - } - long beginTimeMillis = Math.max(System.currentTimeMillis() - timeFilterItem.getTime(), - Instant.EPOCH.toEpochMilli()); - mPermissionUsages.load(mAppInfo.uid, mPackageName, null, beginTimeMillis, Long.MAX_VALUE, - PermissionUsages.USAGE_FLAG_LAST | PermissionUsages.USAGE_FLAG_HISTORICAL, - getActivity().getLoaderManager(), - true, false, this::updateUi, false); - } -} diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java index 550bdaa06..308ab50f3 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java @@ -283,24 +283,7 @@ public final class AppPermissionsFragment extends SettingsWithLargeHeader { category.addPreference(extraPerms); } - if (allowed.getPreferenceCount() > 0) { - Preference details = new Preference(context); - details.setTitle(R.string.detailed_usage_link); - details.setOnPreferenceClickListener(preference -> { - Intent intent = new Intent(Intent.ACTION_REVIEW_APP_PERMISSION_USAGE); - intent.putExtra(Intent.EXTRA_PACKAGE_NAME, - getArguments().getString(Intent.EXTRA_PACKAGE_NAME)); - intent.putExtra(Intent.EXTRA_USER, UserHandle.getUserHandleForUid( - mAppPermissions.getPackageInfo().applicationInfo.uid)); - context.startActivity(intent); - return true; - }); - allowed.addPreference(details); - - if (!Utils.isPermissionsHubEnabled()) { - allowed.removePreference(details); - } - } else { + if (allowed.getPreferenceCount() == 0) { Preference empty = new Preference(context); empty.setTitle(getString(R.string.no_permissions_allowed)); allowed.addPreference(empty); -- GitLab From f90f74d9507972b6d2595713324b8717492459a1 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Thu, 21 Mar 2019 08:39:05 -0700 Subject: [PATCH 466/701] Fix typo in string. Test: None. Change-Id: Idf5eb7e8086632321736d3f8a107d8c340dfbcbe --- res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 57d37d8fd..2f293ea11 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -305,7 +305,7 @@ Most recent access in the last hour - A=Most recent access in last 15 minutes + Most recent access in last 15 minutes Most recent access in last 1 minute -- GitLab From 711c13b727630d6db8af682eb97c33216a517c29 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Thu, 21 Mar 2019 10:37:54 -0700 Subject: [PATCH 467/701] Fix permission icon on filter dialog in dark mode. Fixes: 129058529 Test: View dialog in light and dark mode. Change-Id: I993dacf032fc877f95d99a528a970c1c87f7c2e3 --- .../permission/ui/handheld/PermissionUsageFragment.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java index cfc23bcdf..0e4f7eff8 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java @@ -890,7 +890,10 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements View itemView = layoutInflater.inflate(R.layout.permission_filter_dialog_item, itemsListView, false); - ((ImageView) itemView.requireViewById(R.id.icon)).setImageResource(icons[i]); + ((ImageView) itemView.requireViewById(R.id.icon)).setImageDrawable( + icons[i] == 0 ? null : Utils.applyTint(getActivity(), + getActivity().getDrawable(icons[i]), + android.R.attr.colorControlNormal)); ((TextView) itemView.requireViewById(R.id.title)).setText(elems[i]); ((TextView) itemView.requireViewById(R.id.summary)).setText( getActivity().getResources().getQuantityString( -- GitLab From 72d3ac4ab8b2bf1559dd79913b7076828dc3b26e Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Wed, 20 Mar 2019 15:09:29 -0700 Subject: [PATCH 468/701] Add a dialog allowing the user to filter usages by time. Test: Use the filter. Change-Id: Iad77d380b2cd2203bcaa0b6d0e173b4b20ef0337 --- res/values/strings.xml | 5 +- .../ui/handheld/PermissionUsageFragment.java | 66 ++++++++++++++++++- 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 4fd64126c..cfbddedf0 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -302,7 +302,7 @@ Most recent access in last 24 hours - Most recent access in the last hour + Most recent access in last 1 hour A=Most recent access in last 15 minutes @@ -325,6 +325,9 @@ Filter by permissions + + Filter by time + Most permissions diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java index cfc23bcdf..444ff5aa5 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java @@ -87,7 +87,8 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements private static final int MENU_SORT_BY_APP = MENU_HIDE_SYSTEM + 1; private static final int MENU_SORT_BY_TIME = MENU_HIDE_SYSTEM + 2; private static final int MENU_FILTER_BY_PERMISSIONS = MENU_HIDE_SYSTEM + 3; - private static final int MENU_REFRESH = MENU_HIDE_SYSTEM + 4; + private static final int MENU_FILTER_BY_TIME = MENU_HIDE_SYSTEM + 4; + private static final int MENU_REFRESH = MENU_HIDE_SYSTEM + 5; private static final String KEY_SHOW_SYSTEM_PREFS = "_show_system"; private static final String SHOW_SYSTEM_KEY = PermissionUsageFragment.class.getName() @@ -291,6 +292,7 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements mSortByApp = menu.add(Menu.NONE, MENU_SORT_BY_APP, Menu.NONE, R.string.sort_by_app); mSortByTime = menu.add(Menu.NONE, MENU_SORT_BY_TIME, Menu.NONE, R.string.sort_by_time); menu.add(Menu.NONE, MENU_FILTER_BY_PERMISSIONS, Menu.NONE, R.string.filter_by_permissions); + menu.add(Menu.NONE, MENU_FILTER_BY_TIME, Menu.NONE, R.string.filter_by_time); if (mHasSystemApps) { mShowSystemMenu = menu.add(Menu.NONE, MENU_SHOW_SYSTEM, Menu.NONE, R.string.menu_show_system); @@ -325,6 +327,9 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements case MENU_FILTER_BY_PERMISSIONS: showPermissionFilterDialog(); break; + case MENU_FILTER_BY_TIME: + showTimeFilterDialog(); + break; case MENU_SHOW_SYSTEM: case MENU_HIDE_SYSTEM: mShowSystem = item.getItemId() == MENU_SHOW_SYSTEM; @@ -909,6 +914,65 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements } } + private void showTimeFilterDialog() { + Context context = getPreferenceManager().getContext(); + + CharSequence[] labels = new CharSequence[mFilterAdapterTime.getCount()]; + for (int i = 0; i < labels.length; i++) { + labels[i] = mFilterAdapterTime.getFilter(i).getLabel(); + } + int selection = mFilterSpinnerTime.getSelectedItemPosition(); + + // Create the dialog + Bundle args = new Bundle(); + args.putCharSequence(TimeFilterDialog.TITLE, + context.getString(R.string.filter_by_title)); + args.putCharSequenceArray(TimeFilterDialog.ELEMS, labels); + args.putInt(TimeFilterDialog.SELECTION, selection); + TimeFilterDialog chooserDialog = new TimeFilterDialog(); + chooserDialog.setArguments(args); + chooserDialog.setTargetFragment(this, 0); + chooserDialog.show(getFragmentManager().beginTransaction(), + TimeFilterDialog.class.getName()); + } + + /** + * Callback when the user selects a time by which to filter. + * + * @param selectedIndex The index of the dialog option selected by the user. + */ + private void onTimeSelected(int selectedIndex) { + mFilterSpinnerTime.setSelection(selectedIndex); + reloadData(); + } + + /** + * A dialog that allows the user to select a time by which to filter entries. + * + * @see #showTimeFilterDialog() + */ + public static class TimeFilterDialog extends DialogFragment { + private static final String TITLE = TimeFilterDialog.class.getName() + ".arg.title"; + private static final String ELEMS = TimeFilterDialog.class.getName() + ".arg.elems"; + private static final String SELECTION = TimeFilterDialog.class.getName() + ".arg.selection"; + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + PermissionUsageFragment fragment = (PermissionUsageFragment) getTargetFragment(); + CharSequence[] elems = getArguments().getCharSequenceArray(ELEMS); + AlertDialog.Builder b = new AlertDialog.Builder(getActivity()) + .setTitle(getArguments().getCharSequence(TITLE)) + .setSingleChoiceItems(elems, getArguments().getInt(SELECTION), + (dialog, which) -> { + dismissAllowingStateLoss(); + fragment.onTimeSelected(which); + } + ); + + return b.create(); + } + } + /** * A spinner item representing different ways to sort the entries. */ -- GitLab From 75faa686a3d0d34777384bb0ef66c68a52b5891e Mon Sep 17 00:00:00 2001 From: Narayan Kamath Date: Thu, 21 Mar 2019 19:00:39 +0000 Subject: [PATCH 469/701] LocationAccessCheck: Update default DELAY_CHECK_MILLIS to 1 day. Bug: 124385881 Test: make Change-Id: Idfbbf6f020e9b18d400e99ace167e12ff0121965 --- .../permission/service/LocationAccessCheck.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/com/android/packageinstaller/permission/service/LocationAccessCheck.java b/src/com/android/packageinstaller/permission/service/LocationAccessCheck.java index c809981fc..14209741b 100644 --- a/src/com/android/packageinstaller/permission/service/LocationAccessCheck.java +++ b/src/com/android/packageinstaller/permission/service/LocationAccessCheck.java @@ -54,7 +54,6 @@ import static com.android.packageinstaller.permission.utils.Utils.isLocationAcce import static java.lang.System.currentTimeMillis; import static java.util.concurrent.TimeUnit.DAYS; -import static java.util.concurrent.TimeUnit.MINUTES; import android.app.AppOpsManager; import android.app.AppOpsManager.HistoricalOps; @@ -171,13 +170,13 @@ public class LocationAccessCheck { /** * Get the delay in between granting a permission and the follow up check. * - *

Default: 10 minutes + *

Default: 1 day * * @return The delay in milliseconds */ private long getDelayMillis() { return Settings.Secure.getLong(mContentResolver, - LOCATION_ACCESS_CHECK_DELAY_MILLIS, MINUTES.toMillis(10)); + LOCATION_ACCESS_CHECK_DELAY_MILLIS, DAYS.toMillis(1)); } /** -- GitLab From b4468d34b46edda2f76deeb71d6b45bd3a5e08bd Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Thu, 21 Mar 2019 13:51:24 -0700 Subject: [PATCH 470/701] Persist changes to policy changed flags We have to mark the AppPermissions as "delayChanges" so that later app.persistChanges does anything. Fixes: 127285797 Test: atest CtsDevicePolicyManagerTestCases:com.android.cts.devicepolicy.MixedDeviceOwnerTest#testPermissionGrant Change-Id: I5ae04fc0db8e9b9d81f8c32bd9a5e585b58df716 --- .../permission/service/PermissionControllerServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java b/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java index 0178bca88..d06c74889 100644 --- a/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java +++ b/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java @@ -514,7 +514,7 @@ public final class PermissionControllerServiceImpl extends PermissionControllerS Collections.singletonList(unexpandedPermission), callerPkgInfo.applicationInfo.targetSdkVersion); - AppPermissions app = new AppPermissions(this, pkgInfo, false, null); + AppPermissions app = new AppPermissions(this, pkgInfo, false, true, null); int numPerms = expandedPermissions.size(); for (int i = 0; i < numPerms; i++) { -- GitLab From 142f6059c9bb19701c5432080c6bab43b04052f5 Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Thu, 21 Mar 2019 14:23:01 -0700 Subject: [PATCH 471/701] Do not revoke, just deny when policy says so When the permission policy is set as PERMISSION_POLICY_AUTO_DENY, just deny permission requests, do not revoke the permissions. This is what the behavior used to be, so don't change it. Test: atest --test-mapping src/com/android/packageinstaller/permission/service:postsubmit (This includes permission related CtsDevicePolicyManagerTestCases) Change-Id: I9473adf7778cf48519e9d7255989d41dfee5501c --- .../permission/ui/GrantPermissionsActivity.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java b/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java index d51f56b63..ce28a1196 100644 --- a/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java +++ b/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java @@ -184,9 +184,6 @@ public class GrantPermissionsActivity extends Activity } break; case DevicePolicyManager.PERMISSION_POLICY_AUTO_DENY: { - if (group.areRuntimePermissionsGranted()) { - group.revokeRuntimePermissions(false, new String[]{permission}); - } state.mState = GroupState.STATE_DENIED; group.setPolicyFixed(); skipGroup = true; -- GitLab From 7d33303929cac57efa0291443321c8f66e354423 Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Wed, 20 Mar 2019 16:12:03 -0700 Subject: [PATCH 472/701] Use getDeclaredShareLibraries() for role qualification checking. Bug: 124452117 Test: build Change-Id: If56ca2c66200697d30d9ad5ce8642f100e63f8c6 --- AndroidManifest.xml | 1 + src/com/android/packageinstaller/role/model/Role.java | 9 +++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 9914e344e..6b5de5b84 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -29,6 +29,7 @@ + diff --git a/src/com/android/packageinstaller/role/model/Role.java b/src/com/android/packageinstaller/role/model/Role.java index 5240bfb21..033433cfb 100644 --- a/src/com/android/packageinstaller/role/model/Role.java +++ b/src/com/android/packageinstaller/role/model/Role.java @@ -22,6 +22,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; import android.os.Process; import android.os.UserHandle; import android.util.ArrayMap; @@ -447,12 +448,16 @@ public class Role { // TODO: STOPSHIP: Check for disabled packages? - // TODO: STOPSHIP: Add and check PackageManager.getSharedLibraryInfo(). - if (applicationInfo.isInstantApp()) { return false; } + PackageManager userPackageManager = UserUtils.getUserContext(context, user) + .getPackageManager(); + if (!userPackageManager.getDeclaredSharedLibraries(packageName, 0).isEmpty()) { + return false; + } + return true; } -- GitLab From 197a2fa93f6df06962cc2ff2e4af3eb715ee7fc3 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Thu, 21 Mar 2019 17:19:27 -0700 Subject: [PATCH 473/701] Add strings for the new bar chart. These strings will be needed for the new bar chart. Test: Build. Change-Id: I05110cf0f0ca86a66f3cc53c7dde927834c36cdf --- res/values/strings.xml | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 4fd64126c..82f9192be 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -310,8 +310,35 @@ Most recent access in last 1 minute + + Permission usage at any time + + + Permission usage in last 7 days + + + Permission usage in last 24 hours + + + Permission usage in last 1 hour + + + Permission usage in last 15 minutes + + + Permission usage in last 1 minute + - Apps + + Used by:\n1 app + Used by:\n%s apps + + + + See all in Dashboard + + +   Filtered by: %1$s -- GitLab From f11c428434c7145fec158a39d4e86e414290311b Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Thu, 21 Mar 2019 18:27:27 -0700 Subject: [PATCH 474/701] Launch the new default home when one is selected. This was the old behavior from Settings. Bug: 124452117 Test: manual Change-Id: Ie401cf8b82c3a2b254fa3748611126b8cb63bbc1 --- res/xml/roles.xml | 3 -- .../role/model/HomeRoleBehavior.java | 11 ++++++ .../packageinstaller/role/model/Role.java | 39 +++++++++++++------ .../role/model/RoleBehavior.java | 6 +++ .../service/RoleControllerServiceImpl.java | 2 +- .../role/ui/DefaultAppFragment.java | 7 +++- .../role/ui/DefaultAppListFragment.java | 3 +- .../ui/ManageRoleHolderStateLiveData.java | 36 +++++++++++++++++ .../role/ui/RequestRoleFragment.java | 14 +++++-- .../role/ui/SpecialAppAccessFragment.java | 5 +++ 10 files changed, 106 insertions(+), 20 deletions(-) diff --git a/res/xml/roles.xml b/res/xml/roles.xml index d320c5da8..36b1fe2d8 100644 --- a/res/xml/roles.xml +++ b/res/xml/roles.xml @@ -290,7 +290,6 @@ - - Call redirecting app - Call screening app + Caller ID and spam app Call companion app -- GitLab From a69cce125eca1e5b2dd353977ca362573822ac6c Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Fri, 22 Mar 2019 13:09:25 -0700 Subject: [PATCH 476/701] Update strings for grandfathered storage warning Test: Looked at dialog Fixes: 128920157 Change-Id: I2f25715a2dadebfe85371f4142c893f0b60712e5 --- res/values/strings.xml | 4 ++-- .../permission/ui/handheld/AppPermissionFragment.java | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 3801bc227..07dfc5122 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -644,10 +644,10 @@ Allow %4$s to upload a bug repo - Uninstall the app as permission can\u2019t be denied + Permission can\u2019t be denied. Uninstall %1$s. - %1$s has legacy storage permission to keep your previous data accessible.\n\nYou need to uninstall this app and reinstall it, as the app can stop working if this permission is denied. + %1$s has legacy storage permission to keep your previous data accessible, and the app can stop working when this permission is denied.\n\nTo continue using the app, uninstall it and then reinstall it. Your data in this app may be lost. Got it diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java index d909ab4ce..426b3d117 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java @@ -879,17 +879,20 @@ public class AppPermissionFragment extends SettingsWithLargeHeader { ApplicationInfo appInfo = getArguments().getParcelable(APP_INFO); + String appLabel = Utils.getFullAppLabel(appInfo, context); View header = LayoutInflater.from(context).inflate(R.layout.dialog_header, null); ((ImageView) header.requireViewById(R.id.icon)).setImageDrawable( context.getDrawable(R.drawable.ic_warning)); ((TextView) header.requireViewById(R.id.title)).setText( - R.string.grandfathered_modern_storage_permission_deny_warning_title); + context.getString( + R.string.grandfathered_modern_storage_permission_deny_warning_title, + appLabel)); AlertDialog.Builder b = new AlertDialog.Builder(context) .setCustomTitle(header) .setMessage(context.getString( R.string.grandfathered_modern_storage_permission_deny_warning_content, - Utils.getFullAppLabel(appInfo, context))) + appLabel)) .setPositiveButton(R.string.dismiss_with_acknowledgment, null); return b.create(); -- GitLab From c02bafef51fc6aff3cc0910a9fcc5a63fb1056ef Mon Sep 17 00:00:00 2001 From: Evan Severson Date: Thu, 21 Mar 2019 08:41:46 -0700 Subject: [PATCH 477/701] Make strings for tri-state permission consistent Also fixed a mistake where the wrong, but currently equivalent, string was used Test: Check each case Fixes:124396162 Change-Id: I8ae7d1a9416c9c5d8894d960ab19d2d26b786e0a --- res/values/strings.xml | 10 +++++----- .../permission/ui/GrantPermissionsActivity.java | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 57d37d8fd..c0ee9cb0f 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -97,7 +97,7 @@ Allow all the time - Allow only while the app is in use + Allow only while using the app Allow all the time @@ -190,13 +190,13 @@ - Always + Allow all the time - Only while using app + Allow only while using the app - Never + Deny Loading\u2026 @@ -371,7 +371,7 @@ Allow all the time - Allow only while the app is in use + Allow only while using the app Deny diff --git a/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java b/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java index d51f56b63..4c5449c6f 100644 --- a/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java +++ b/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java @@ -665,7 +665,7 @@ public class GrantPermissionsActivity extends Activity messageId = groupState.mGroup.getBackgroundRequest(); detailMessageId = groupState.mGroup.getBackgroundRequestDetail(); buttonLabels[LABEL_ALLOW_BUTTON] = - getString(R.string.grant_dialog_button_allow_always); + getString(R.string.grant_dialog_button_allow_background); buttonLabels[LABEL_DENY_BUTTON] = getString(R.string.grant_dialog_button_deny_background); buttonLabels[LABEL_DENY_AND_DONT_ASK_AGAIN_BUTTON] = -- GitLab From b8a0e7e47958c1db7a99c768bd8baf7bd2dfcca8 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Thu, 21 Mar 2019 17:33:31 -0700 Subject: [PATCH 478/701] Mark the current mode as checked in the permission filter dialog. Fixes: 129072522 Test: Click various filters and ensure the right one is selected. Change-Id: I2fd006975234226d785276ad27c9277b9acf7241 --- .../permission/ui/handheld/PermissionUsageFragment.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java index 0e4f7eff8..6ef5f9e29 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java @@ -37,6 +37,7 @@ import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemSelectedListener; import android.widget.ImageView; +import android.widget.RadioButton; import android.widget.Spinner; import android.widget.TextView; @@ -877,6 +878,7 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements String[] groups = getArguments().getStringArray(GROUPS); int[] icons = getArguments().getIntArray(ICONS); int[] accessCounts = getArguments().getIntArray(ACCESS_COUNTS); + int selectedIndex = getArguments().getInt(SELECTION); LayoutInflater layoutInflater = LayoutInflater.from(fragment.getActivity()); View view = layoutInflater.inflate(R.layout.permission_filter_dialog, null); @@ -905,6 +907,9 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements fragment.onPermissionGroupSelected(groupName); }); + ((RadioButton) itemView.requireViewById(R.id.radio_button)).setChecked( + i == selectedIndex); + itemsListView.addView(itemView); } -- GitLab From b511f2cb43e8b9339752eb443e6fca5456123067 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Fri, 22 Mar 2019 16:07:30 -0700 Subject: [PATCH 479/701] Center permission description in header. Fixes: 129144991 Test: View one-line and two-line descriptions. Change-Id: I2feb83245536f9058ba47da9505c75d9dda07b49 --- res/values/styles.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/res/values/styles.xml b/res/values/styles.xml index 16198d029..d8da231dd 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -195,6 +195,7 @@ wrap_content wrap_content 16dp + center_horizontal ?android:attr/colorAccent ?android:attr/listPreferredItemPaddingStart ?android:attr/listPreferredItemPaddingEnd -- GitLab From 7c425935ff0c7713e5d3793104cca2356f5b926c Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Fri, 22 Mar 2019 16:32:22 -0700 Subject: [PATCH 480/701] Tweak string for system fixed permissions. Fixes: 129159733 Test: View string. Change-Id: I282598ee68cf3de4679ff3ad2902c13ad07c94a7 --- res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 3801bc227..6afc94d7b 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -181,7 +181,7 @@ Foreground access enabled by admin - Permission set by system + Device requires this permission to operate @string/permission_access_always -- GitLab From 15b036abd8aa827e903af40fdca3a250311f7943 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Fri, 22 Mar 2019 16:37:52 -0700 Subject: [PATCH 481/701] Tweak permission toggle strings. Fixes: 129145189 Test: View strings. Change-Id: Icdf51ca66e5d624dbdcd5bda4c13edd6756ce343 --- res/values/strings.xml | 6 +++--- .../permission/ui/handheld/AppPermissionFragment.java | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 3801bc227..5c1df64cb 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -383,16 +383,16 @@ %1$s access for this app - %1$s accessed your %2$s %3$s ago. + %1$s accessed your %2$s %3$s ago - %1$s has not accessed your %2$s. + %1$s has not accessed your %2$s See all %1$s permissions - See all apps with the %1$s permission + See all apps with this permission Apps with this permission can %1$s diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java index d909ab4ce..7c5e1b9dd 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java @@ -217,8 +217,7 @@ public class AppPermissionFragment extends SettingsWithLargeHeader { }); TextView footer2Link = root.requireViewById(R.id.footer_link_2); - footer2Link.setText(context.getString(R.string.app_permission_footer_permission_apps_link, - mGroup.getLabel())); + footer2Link.setText(context.getString(R.string.app_permission_footer_permission_apps_link)); footer2Link.setOnClickListener((v) -> { Intent intent = new Intent(Intent.ACTION_MANAGE_PERMISSION_APPS); intent.putExtra(Intent.EXTRA_PERMISSION_NAME, mGroup.getName()); -- GitLab From 7cad62318fb8608d4d075c53a847ba2b59d8bfbf Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Sat, 23 Mar 2019 09:59:33 -0700 Subject: [PATCH 482/701] Import translations. DO NOT MERGE Change-Id: Ib49910097af4412ce48855d5653e4788c617385b Auto-generated-cl: translation import --- res/values-ar/strings.xml | 194 ++++++++++++++++++++++------------ res/values-ca/strings.xml | 178 ++++++++++++++++++++++--------- res/values-de/strings.xml | 178 ++++++++++++++++++++++--------- res/values-es/strings.xml | 178 ++++++++++++++++++++++--------- res/values-eu/strings.xml | 178 ++++++++++++++++++++++--------- res/values-fr-rCA/strings.xml | 178 ++++++++++++++++++++++--------- res/values-fr/strings.xml | 178 ++++++++++++++++++++++--------- res/values-hy/strings.xml | 185 ++++++++++++++++++++++---------- res/values-kk/strings.xml | 178 ++++++++++++++++++++++--------- res/values-kn/strings.xml | 185 ++++++++++++++++++++++---------- res/values-mr/strings.xml | 178 ++++++++++++++++++++++--------- res/values-pt-rPT/strings.xml | 180 ++++++++++++++++++++++--------- res/values-sk/strings.xml | 186 ++++++++++++++++++++++---------- res/values-ta/strings.xml | 178 ++++++++++++++++++++++--------- res/values-vi/strings.xml | 185 ++++++++++++++++++++++---------- 15 files changed, 1921 insertions(+), 796 deletions(-) diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml index 71b1022e7..4d1297b27 100644 --- a/res/values-ar/strings.xml +++ b/res/values-ar/strings.xml @@ -23,6 +23,10 @@ "لم يتمّ العثور على التطبيق." "رفض" "رفض وعدم طرح السؤال مرةً أخرى" + + + + "معلومات أكثر" "رفض على أيّ حال" "%1$s من %2$s" @@ -36,7 +40,10 @@ "ليس هناك أذونات موقوفة." "سماح" "السماح طوال الوقت" - "السماح فقط أثناء استخدام التطبيق" + + + + "تطبيقات" "أذونات التطبيق" "مدير الأذونات" @@ -55,8 +62,6 @@ "‏تمّ تصميم هذا التطبيق لإصدار قديم من Android. وقد يؤدي رفض الإذن إلى عدم العمل على النحو المطلوب مرة أخرى." "تنفيذ إجراء غير معروف" "تمّ السماح لـ %1$d من أصل %2$d تطبيق" - "الاستخدام الأخير" - "عرض لوحة التحكم في الأذونات" "عرض النظام" "إخفاء النظام" "ليس هناك أيّ تطبيقات." @@ -71,13 +76,17 @@ "أوقف المشرف وصول التطبيق للبيانات أثناء عدم نشاطه." "فعَّل المشرف وصول التطبيق للبيانات أثناء عدم نشاطه." "فعَّل المشرف وصول التطبيق للبيانات أثناء نشاطه." - "تم ضبط الإذن بواسطة النظام." + + - "دومًا" - "أثناء استخدام التطبيق فقط" - "مطلقًا" + + + + + + "جارٍ التحميل…" "كل الأذونات" "إمكانات التطبيق الأخرى" @@ -96,38 +105,10 @@ "جارٍ الطرح المرحلي للتطبيق…" "غير معروف" "لوحة التحكّم" - - آخر إذن وصول: %1$s\n%2$s إذن وصول - آخر إذن وصول: %1$s\nإذنا وصول (%2$s) - آخر إذن وصول: %1$s\n%2$s أذونات وصول - آخر إذن وصول: %1$s\n%2$s إذن وصول - آخر إذن وصول: %1$s\n%2$s إذن وصول - آخر إذن وصول: %1$s\n%2$s إذن وصول - - - آخر إذن وصول: %1$s\n%2$s إذن وصول (%3$s في الخلفية) - آخر إذن وصول: %1$s\nإذنا وصول (%2$s) (%3$s في الخلفية) - آخر إذن وصول: %1$s\n%2$s أذونات وصول (%3$s في الخلفية) - آخر إذن وصول: %1$s\n%2$s إذن وصول (%3$s في الخلفية) - آخر إذن وصول: %1$s\n%2$s إذن وصول (%3$s في الخلفية) - آخر إذن وصول: %1$s\n%2$s إذن وصول (%3$s في الخلفية) - - - آخر إذن وصول: %1$s\n%2$s إذن وصول\nالمدة: %3$s - آخر إذن وصول: %1$s\nإذنا وصول (%2$s)\nالمدة: %3$s - آخر إذن وصول: %1$s\n%2$s أذونات وصول\nالمدة: %3$s - آخر إذن وصول: %1$s\n%2$s إذن وصول\nالمدة: %3$s - آخر إذن وصول: %1$s\n%2$s إذن وصول\nالمدة: %3$s - آخر إذن وصول: %1$s\n%2$s إذن وصول\nالمدة: %3$s - - - آخر إذن وصول: %1$s\n%2$s إذن وصول (%3$s في الخلفية)\nالمدة: %3$s - آخر إذن وصول: %1$s\nإذنا وصول (%2$s) (%3$s في الخلفية)\nالمدة: %3$s - آخر إذن وصول: %1$s\n%2$s أذونات وصول (%3$s في الخلفية)\nالمدة: %3$s - آخر إذن وصول: %1$s\n%2$s إذن وصول (%3$s في الخلفية)\nالمدة: %3$s - آخر إذن وصول: %1$s\n%2$s إذن وصول (%3$s في الخلفية)\nالمدة: %3$s - آخر إذن وصول: %1$s\n%2$s إذن وصول (%3$s في الخلفية)\nالمدة: %3$s - + + + + "أيّ إذن" "أي وقت" "آخر 7 أيام" @@ -136,39 +117,95 @@ "آخر 15 دقيقة" "الدقيقة الماضية" "لم يتمّ استخدام الأذونات" - "الدخول في أيّ وقت" - "الدخول في آخر 7 أيام" - "الدخول في آخر 24 ساعة" - "الدخول في الساعة الماضية" - "الدخول في آخر 15 دقيقة" - "أذونات الوصول خلال الدقيقة الماضية" - "أعلى استخدام للأذونات في أيّ وقت" - "أعلى استخدام للأذونات في آخر 7 أيام" - "أعلى استخدام للأذونات في آخر 24 ساعة" - "أعلى استخدام للأذونات في الساعة الماضية" - "أعلى استخدام للأذونات في آخر 15 دقيقة" - "الأذونات الأكثر استخدامًا خلال الدقيقة الماضية" - "التطبيقات" + + + + + + + + + + + + + + + + + + + + + + + + + + + "تمّت التصفية حسب: %1$s" "إزالة الفلتر" "تصفية بحسب" "تصفية بحسب الأذونات" + + "معظم الأذونات" "معظم مرّات الدخول" "آخر دخول" + + + + + + "إعادة تحميل" + "استخدام أذونات التطبيق" "استخدام الإذن: %1$s مرّة إجمالي المدّة: %2$s. آخر استخدام قبل %3$s." "استخدام الإذن: %1$s مرّة آخر استخدام قبل %2$s." "سماح" "السماح طوال الوقت" - "السماح فقط أثناء استخدام التطبيق" + + "رفض" "إذن %1$s" - "إذن %1$s الممنوح للتطبيق %2$s" - "قبل %3$s، استخدَم تطبيق %1$s إذن %2$s الذي منحته." - "لم يحصل تطبيق %1$s على إذن %2$s." - "عرض تفاصيل استخدام الأذونات" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + "آخر إذن وصول: %1$s" "لم يتم الوصول مطلقًا." "التطبيقات أو الأذونات المسموح بها" @@ -207,8 +244,6 @@ %s ثانية ثانية واحدة - "‏هل تريد الاستفادة من <b>%1$s</b> في دور %2$s؟" - "‏هل تريد الاستفادة من <b>%1$s</b> بدلاً من <b>%1$s</b> في دور %2$s؟" "تذكيرات الأذونات" "يستخدِم التطبيق %s موقعك الجغرافي." "يمكن لهذا التطبيق دائمًا الوصول إلى بيانات موقعك الجغرافي. انقر لتغيير ذلك." @@ -217,19 +252,40 @@ "لم يتم رفض أي أذونات." "لم يتم السماح لأي تطبيقات." "لم يتم رفض أي تطبيقات." - "فتح" - "إلغاء التثبيت" - "فرض الإيقاف" "الإعدادات" "تحظى خدمة %s بوصول كامل إلى جهازك." - "خدمات إمكانية الوصول التي تحظى بوصول كامل إلى جهازك: %s خدمة" + + "يمكن لخدمة %s عرض شاشتك وإجراءاتك ومدخلاتك وتنفيذ الإجراءات والتحكم في العرض." - "يمكن لهذه الخدمات عرض شاشتك وإجراءاتك ومدخلاتك وتنفيذ الإجراءات والتحكم في العرض." + + + + + + + + + + + + + + + + + + + + "التطبيقات التلقائية" "ليست هناك تطبيقات تلقائية." + + "التطبيقات التلقائية للعمل" "بدون" "ليست هناك تطبيقات." + + "أذونات خاصة للتطبيقات" "لا إذن وصول خاص إلى التطبيق." "ليست هناك تطبيقات." @@ -243,9 +299,9 @@ "تطبيق المعرض" "تطبيق الهاتف في وضع السيارة" "تطبيق إعادة توجيه المكالمات" - "تطبيق فحص المكالمات" + + "تطبيق مصاحب للمكالمات" - "‏تطبيق Car Projection" "لا يتوافق التطبيق مع الملف الشخصي للعمل." "ملاحظة: في حال إعادة تشغيل جهازك وضبط قفل شاشة، لا يمكن بدء هذا التطبيق إلى أن تفتح جهازك." "سيتمكن المساعد من قراءة المعلومات عن التطبيقات قيد الاستخدام على نظامك، بما في ذلك المعلومات المرئية على شاشتك أو التي يمكن الوصول إليها داخل التطبيقات." @@ -256,4 +312,10 @@ "يطلب تطبيق %1$s تحميل تقرير خطأ من هذا الجهاز تم تسجيله بتاريخ %2$s في %3$s. وتشمل تقارير الأخطاء المعلومات الشخصية حول جهازك أو المعلومات التي سجلتها التطبيقات، مثل أسماء المستخدمين وبيانات الموقع الجغرافي ومعرّفات الأجهزة ومعلومات الشبكة. ويجب عدم مشاركة تقارير الأخطاء إلا مع المستخدمين والتطبيقات التي تثق بمشاركة هذه المعلومات معها. هل تريد السماح لتطبيق %4$s بتحميل تقرير خطأ؟" "سماح" "رفض" + + + + + + diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml index 633fba207..684e3d361 100644 --- a/res/values-ca/strings.xml +++ b/res/values-ca/strings.xml @@ -23,6 +23,10 @@ "No s\'ha trobat l\'aplicació" "Denega" "Denega i no m\'ho tornis a preguntar" + + + + "Més informació" "Denega igualment" "%1$s de %2$s" @@ -36,7 +40,10 @@ "cap permís desactivat" "Permet" "Permet sempre" - "Permet només mentre s\'utilitza l\'aplicació" + + + + "Aplicacions" "Permisos d\'aplicacions" "Gestor de permisos" @@ -51,8 +58,6 @@ "Aquesta aplicació es va dissenyar per a una versió anterior d\'Android. És possible que no funcioni com està previst si li denegues el permís." "dur a terme una acció desconeguda" "%1$d de %2$d aplicacions permeses" - "Ús recent" - "Consulta el tauler de permisos" "Mostra les aplicacions del sistema" "Amaga les aplicacions del sistema" "Cap aplicació" @@ -67,13 +72,17 @@ "L\'administrador ha desactivat l\'accés en segon pla" "L\'administrador ha activat l\'accés en segon pla" "L\'administrador ha activat l\'accés en primer pla" - "Permís definit pel sistema" + + - "Sempre" - "Només mentre s\'utilitzi l\'app" - "Mai" + + + + + + "S\'està carregant…" "Tots els permisos" "Altres competències de l\'aplicació" @@ -92,22 +101,10 @@ "S\'està preparant la instal·lació de l\'aplicació…" "Desconegut" "Tauler" - - Últim accés: %1$s\n%2$s accessos - Últim accés: %1$s\n%2$s accés - - - Últim accés: %1$s\n%2$s accessos (%3$s en segon pla) - Últim accés: %1$s\n%2$s accés (%3$s en segon pla) - - - Últim accés: %1$s\n%2$s accessos\nDurada: %3$s - Últim accés: %1$s\n%2$s accés\nDurada: %3$s - - - Últim accés: %1$s\n%2$s accessos (%3$s en segon pla)\nDurada: %3$s - Últim accés: %1$s\n%2$s accés (%3$s en segon pla)\nDurada: %3$s - + + + + "Qualsevol permís" "En qualsevol moment" "7 últims dies" @@ -116,39 +113,95 @@ "Últims 15 minuts" "Últim minut" "Cap ús de permisos" - "Accés en qualsevol moment" - "Accés durant els 7 últims dies" - "Accés durant les últimes 24 hores" - "Accés durant l\'última hora" - "Accés durant els últims 15 minuts" - "Accés durant l\'últim minut" - "Permisos més utilitzats en qualsevol moment" - "Permisos més utilitzats durant els 7 últims dies" - "Permisos més utilitzats durant les últimes 24 hores" - "Permisos més utilitzats durant l\'última hora" - "Permisos més utilitzats durant els últims 15 minuts" - "Permisos més utilitzats durant l\'últim minut" - "Aplicacions" + + + + + + + + + + + + + + + + + + + + + + + + + + + "Filtrats per: %1$s" "Suprimeix el filtre" "Filtra per" "Filtra per permisos" + + "Amb més permisos" "Amb més accessos" "Recents" + + + + + + "Actualitza" + "Ús de permisos de l\'aplicació" "Accés: %1$s vegades. Durada total: %2$s. Utilitzada per última vegada fa %3$s." "Accés: %1$s vegades. Utilitzada per última vegada fa %2$s." "Permet" "Permet sempre" - "Permet només mentre s\'utilitza l\'aplicació" + + "Denega" "Permís per accedir a %1$s" - "Accés de l\'aplicació %2$s a %1$s" - "%1$s va accedir fa %3$s a %2$s." - "%1$s no ha accedit al permís %2$s." - "Mostra dades detallades sobre l\'ús de permisos" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + "Últim accés: %1$s" "No hi ha accedit mai" "Acceptats" @@ -171,8 +224,6 @@ %s segons 1 segon - "Vols utilitzar <b>%1$s</b> com a %2$s?" - "Vols utilitzar <b>%1$s</b> en lloc de l\'aplicació <b>%1$s</b> com a %2$s?" "Recordatoris de permisos" "%s ha estat utilitzant la teva ubicació" "Aquesta aplicació pot accedir a la teva ubicació en qualsevol moment. Toca per canviar-ho." @@ -181,19 +232,40 @@ "No s\'ha denegat cap permís" "Cap aplicació té permís" "A cap aplicació se li ha denegat el permís" - "Obre" - "Desinstal·la" - "Força l\'aturada" "Configuració" "%s té accés complet al dispositiu" - "%s serveis d\'accessibilitat tenen accés complet al dispositiu" + + "%s pot veure la pantalla, les accions i el text que s\'introdueix, dur a terme accions i controlar la pantalla." - "Aquests serveis poden veure la pantalla, les accions i el text que s\'introdueix, dur a terme accions i controlar la pantalla." + + + + + + + + + + + + + + + + + + + + "Aplicacions predeterminades" "Cap aplicació predeterminada" + + "Predeterminada per a la feina" "Cap" "Cap aplicació" + + "Accés especial d\'aplicacions" "Sense accés especial d\'apps" "No hi ha cap aplicació" @@ -207,9 +279,9 @@ "Aplicació Galeria" "Aplicació mode de cotxe" "App per redirigir trucades" - "Aplicació per filtrar trucades" + + "Aplicació complementària de trucades" - "Aplicació projecció del cotxe" "No admet perfils professionals" "Nota: si reinicies el dispositiu i has definit un bloqueig de pantalla, l\'aplicació no s\'iniciarà fins que no desbloquegis el dispositiu." "L\'assistent podrà llegir informació sobre les aplicacions que s\'utilitzen al teu sistema; també podrà accedir a la informació que es veu en pantalla o a què accedeixes des de les aplicacions." @@ -220,4 +292,10 @@ "%1$s sol·licita penjar un informe d\'errors des d\'aquest dispositiu generat el dia %2$s (%3$s). Els informes d\'errors inclouen informació personal sobre el dispositiu o informació registrada per les aplicacions, com ara noms d\'usuaris, dades de la ubicació, identificadors del dispositiu i informació de la xarxa. Comparteix informes d\'errors només amb persones i aplicacions de confiança. Vols permetre que %4$s pengi un informe d\'errors?" "Permet" "Denega" + + + + + + diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index 540745a27..6088810a1 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -23,6 +23,10 @@ "App nicht gefunden" "Ablehnen" "Ablehnen & nicht mehr fragen" + + + + "Weitere Infos" "Trotzdem ablehnen" "%1$s von %2$s" @@ -36,7 +40,10 @@ "Keine deaktiviert" "Zulassen" "Immer zulassen" - "Nur zulassen, wenn die App verwendet wird" + + + + "Apps" "App-Berechtigungen" "Berechtigungsmanager" @@ -51,8 +58,6 @@ "Diese App wurde für eine ältere Android-Version entwickelt. Wenn du keine Berechtigung gewährst, funktioniert sie möglicherweise nicht mehr ordnungsgemäß." "Unbekannte Aktion durchführen" "%1$d von %2$d Apps mit Berechtigung" - "Letzte Nutzungen" - "Berechtigungs-Dashboard anzeigen" "System-Apps einblenden" "System-Apps ausblenden" "Keine Apps" @@ -67,13 +72,17 @@ "Hintergrundzugriff vom Administrator deaktiviert" "Hintergrundzugriff vom Administrator aktiviert" "Vordergrundzugriff vom Administrator aktiviert" - "Berechtigung vom System festgelegt" + + - "Immer" - "Nur während der App-Nutzung" - "Nie" + + + + + + "Wird geladen…" "Alle Berechtigungen" "Andere App-Funktionen" @@ -92,22 +101,10 @@ "App wird vorbereitet…" "Unbekannt" "Dashboard" - - Letzter Zugriff: %1$s\n%2$s Zugriffe - Letzter Zugriff: %1$s\n%2$s Zugriff - - - Letzter Zugriff: %1$s\n%2$s Zugriffe (%3$s im Hintergrund) - Letzter Zugriff: %1$s\n%2$s Zugriff (%3$s im Hintergrund) - - - Letzter Zugriff: %1$s\n%2$s Zugriffe\nDauer: %3$s - Letzter Zugriff: %1$s\n%2$s Zugriff\nDauer: %3$s - - - Letzter Zugriff: %1$s\n%2$s Zugriffe (%3$s im Hintergrund)\nDauer: %3$s - Letzter Zugriff: %1$s\n%2$s Zugriff (%3$s im Hintergrund)\nDauer: %3$s - + + + + "Beliebige Berechtigung" "Beliebiger Zeitraum" "Letzte 7 Tage" @@ -116,39 +113,95 @@ "Letzte 15 Minuten" "In der letzten Minute" "Keine Berechtigungen verwendet" - "Zugriff in der gesamten Zeit" - "Zugriff in den letzten 7 Tagen" - "Zugriff in den letzen 24 Stunden" - "Zugriff in der letzten Stunde" - "Zugriff in den letzten 15 Minuten" - "Zugriff in der letzten Minute" - "Häufigste Berechtigungsnutzungen (gesamte Zeit)" - "Meiste Berechtigungsnutzungen (letzte 7 Tage)" - "Meiste Berechtigungsnutzungen (letzte 24 Stunden)" - "Häufigste Berechtigungsnutzungen (letzte Stunde)" - "Meiste Berechtigungsnutzungen (letzte 15 Minuten)" - "Häufigste Berechtigungsnutzungen (letzte Minute)" - "Apps" + + + + + + + + + + + + + + + + + + + + + + + + + + + "Gefiltert nach: %1$s" "Filter entfernen" "Filtern nach" "Nach Berechtigungen filtern" + + "Meiste Berechtigungen" "Meiste Zugriffe" "Letzte" + + + + + + "Aktualisieren" + "Nutzung von App-Berechtigungen" "Zugriff: %1$s Mal. Gesamtdauer: %2$s. Zuletzt verwendet vor %3$s." "Zugriff: %1$s Mal. Zuletzt verwendet vor %2$s" "Zulassen" "Immer zulassen" - "Nur zulassen, wenn die App verwendet wird" + + "Nicht zulassen" "Berechtigung \"%1$s\"" - "Zugriff auf %1$s für %2$s" - "%1$s hat vor %3$s auf %2$s zugegriffen." - "%1$s hat nicht auf %2$s zugegriffen." - "Details zur Berechtigungsnutzung ansehen" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + "Letzter Zugriff: %1$s" "Nie auf Berechtigung zugegriffen" "Zulässig" @@ -171,8 +224,6 @@ %s Sekunden 1 Sekunde - "<b>%1$s</b> als %2$s verwenden?" - "<b>%1$s</b> anstelle von <b>%1$s</b> als %2$s verwenden?" "Berechtigungserinnerungen" "%s hat deinen Standort verwendet" "Diese App kann immer auf deinen Standort zugreifen. Zum Ändern hier tippen." @@ -181,19 +232,40 @@ "Alle Berechtigungen zugelassen" "Keine Apps zugelassen" "Alle Apps zugelassen" - "Öffnen" - "Deinstallieren" - "Beenden erzwingen" "Einstellungen" "%s hat uneingeschränkten Zugriff auf dein Gerät" - "%s Bedienungshilfen-Dienste haben uneingeschränkten Zugriff auf dein Gerät" + + "%s kann deinen Bildschirm, deine Aktionen und deine Eingaben sehen, Aktionen ausführen und den Bildschirm steuern." - "Diese Dienste können deinen Bildschirm, deine Aktionen und deine Eingaben sehen, Aktionen ausführen und den Bildschirm steuern." + + + + + + + + + + + + + + + + + + + + "Standard-Apps" "Keine Standard-Apps" + + "Standardeinstellung für Arbeit" "Keine" "Keine Apps" + + "Spezieller App-Zugriff" "Kein spezieller App-Zugriff" "Keine Apps" @@ -207,9 +279,9 @@ "Galerie App" "Automodus-Telefon-App" "App zur Anrufweiterleitung" - "Call Screening-App" + + "Companion App für Anrufe" - "App \"Übertragung an Auto\"" "Unterstützt das Arbeitsprofil nicht" "Hinweis: Hinweis: Wenn du dein Gerät neu startest und eine Displaysperre aktiviert ist, wird diese App erst gestartet, wenn du dein Gerät entsperrst." "Der Assistent kann Informationen zu Apps abrufen, die du auf deinem System verwendest, einschließlich Informationen, die auf deinem Bildschirm angezeigt werden oder die in Apps zugänglich sind." @@ -220,4 +292,10 @@ "%1$s möchte einen Fehlerbericht von diesem Gerät hochladen, der am %2$s um %3$s erstellt wurde. Fehlerberichte enthalten Informationen zu deinem Gerät, die du persönlich eingegeben hast oder die von Apps aufgezeichnet werden, z. B. Nutzernamen, Standortdaten, Geräte-IDs und Netzwerkinformationen. Teile Fehlerberichte nur mit Personen und Apps, denen du vertraust. Darf %4$s einen Fehlerbericht hochladen?" "Zulassen" "Ablehnen" + + + + + + diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index 6b7e736bd..e8d9a63a3 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -23,6 +23,10 @@ "Aplicación no encontrada" "Denegar" "Denegar y no volver a preguntar" + + + + "Más información" "Denegar" "%1$s de %2$s" @@ -36,7 +40,10 @@ "ninguno inhabilitado" "Permitir" "Permitir siempre" - "Permitir solo mientras la aplicación está en uso" + + + + "Aplicaciones" "Permisos de aplicaciones" "Gestor de permisos" @@ -51,8 +58,6 @@ "Esta aplicación está diseñada para una versión anterior de Android. Si se le deniega el permiso, puede dejar de funcionar de la forma prevista." "realizar una acción desconocida" "%1$d de %2$d aplicaciones permitidas" - "Uso reciente" - "Ver panel de permisos" "Mostrar aplicaciones del sistema" "Ocultar aplicaciones del sistema" "No hay aplicaciones" @@ -67,13 +72,17 @@ "El administrador ha inhabilitado el acceso en segundo plano" "El administrador ha habilitado el acceso en segundo plano" "El administrador ha habilitado el acceso en primer plano" - "Permiso establecido por el sistema" + + - "Siempre" - "Solo mientras se usa la app" - "Nunca" + + + + + + "Cargando…" "Todos los permisos" "Otras funciones de la aplicación" @@ -92,22 +101,10 @@ "Preparando aplicación…" "Desconocida" "Panel" - - Último acceso: %1$s\n%2$s accesos - Último acceso: %1$s\n%2$s acceso - - - Último acceso: %1$s\n%2$s accesos (%3$s en segundo plano) - Último acceso: %1$s\n%2$s acceso (%3$s en segundo plano) - - - Último acceso: %1$s\n%2$s accesos\nDuración: %3$s - Último acceso: %1$s\n%2$s acceso\nDuración: %3$s - - - Último acceso: %1$s\n%2$s accesos (%3$s en segundo plano)\nDuración: %3$s - Último acceso: %1$s\n%2$s acceso (%3$s en segundo plano)\nDuración: %3$s - + + + + "Cualquier permiso" "Cualquier fecha" "Últimos 7 días" @@ -116,39 +113,95 @@ "Últimos 15 minutos" "Último minuto" "No se han usado los permisos" - "Acceso en cualquier momento" - "Acceso en los últimos 7 días" - "Acceso en las últimas 24 horas" - "Acceso en la última hora" - "Acceso en los últimos 15 minutos" - "Acceso en el último minuto" - "Permisos más usados en cualquier momento" - "Permisos más usados en los últimos 7 días" - "Permisos más usados en las últimas 24 horas" - "Permisos más usados en la última hora" - "Permisos más usados en los últimos 15 minutos" - "Permisos más usados en el último minuto" - "Apps" + + + + + + + + + + + + + + + + + + + + + + + + + + + "Filtrados por: %1$s" "Quitar filtro" "Filtrar por" "Filtrar por permisos" + + "Mayor número de permisos" "Mayor número de accesos" "Recientes" + + + + + + "Actualizar" + "Uso permisos de la aplicación" "Acceso: %1$s veces. Duración total: %2$s. Último uso: hace %3$s." "Acceso: %1$s veces. Último uso: hace %2$s." "Permitir" "Permitir siempre" - "Permitir solo mientras las aplicaciones están en uso" + + "Denegar" "Permiso de %1$s" - "Acceso de %2$s a tu %1$s" - "%1$s ha accedido a tu %2$s hace %3$s." - "%1$s no ha accedido a tu %2$s." - "Ver el uso de permisos detallado" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + "Último acceso: %1$s" "No se ha accedido nunca" "Permitidos" @@ -171,8 +224,6 @@ %s segundos 1 segundo - "¿Quieres usar <b>%1$s</b> como tu %2$s?" - "¿Quieres usar <b>%1$s</b> en lugar de <b>%1$s</b> como tu %2$s?" "Recordatorios de permisos" "%s ha estado usando tu ubicación" "Esta aplicación puede acceder siempre a tu ubicación. Toca para cambiarlo." @@ -181,19 +232,40 @@ "No se ha denegado ningún permiso" "Ninguna aplicación tiene permiso" "A ninguna aplicación se le ha denegado el permiso" - "Abrir" - "Desinstalar" - "Forzar detención" "Ajustes" "%s tiene acceso completo a tu dispositivo" - "%s servicios de accesibilidad tienen acceso completo a tu dispositivo" + + "%s puede ver tu pantalla, lo que haces y lo que introduces; realizar acciones; y controlar la pantalla." - "Estos servicios pueden ver tu pantalla, lo que haces y lo que introduces; realizar acciones; y controlar la pantalla." + + + + + + + + + + + + + + + + + + + + "Aplicaciones predeterminadas" "Ninguna app predeterminada" + + "Predeterminadas para trabajo" "Ninguna" "No hay aplicaciones" + + "Acceso especial de apps" "Sin acceso especial de apps" "No hay aplicaciones" @@ -207,9 +279,9 @@ "Aplicación de galería" "App de llamadas en modo coche" "App de redirección de llamadas" - "App de filtro de llamadas" + + "App complementaria de llamadas" - "App de proyección del coche" "No admite perfiles de trabajo" "Nota: Si reinicias el dispositivo y y has definido un bloqueo de pantalla, esta aplicación no se podrá iniciar hasta que desbloquees el dispositivo." "El asistente podrá consultar información sobre las aplicaciones en uso del sistema, como la que aparezca en pantalla o a la que se pueda acceder a través de las aplicaciones." @@ -220,4 +292,10 @@ "%1$s quiere subir el informe de errores de este dispositivo, generado el %2$s a las %3$s. Los informes de errores incluyen información personal sobre el dispositivo o datos registrados por las aplicaciones, como nombres de usuario, datos de ubicación, identificadores del dispositivo e información de red. Comparte estos informes únicamente con personas y aplicaciones de confianza. ¿Quieres permitir que %4$s suba un informe de errores?" "Permitir" "Denegar" + + + + + + diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml index 55d8ec15e..e2bdaefa5 100644 --- a/res/values-eu/strings.xml +++ b/res/values-eu/strings.xml @@ -23,6 +23,10 @@ "Ez da aurkitu aplikazioa" "Ukatu" "Ukatu eta ez galdetu berriro" + + + + "Datu gehiago" "Ukatu hala ere" "%1$s/%2$s" @@ -36,7 +40,10 @@ "guztiak gaituta" "Baimendu" "Baimendu beti" - "Baimendu aplikazioa erabiltzen ari zarenean soilik" + + + + "Aplikazioak" "Aplikazio-baimenak" "Baimenen kudeatzailea" @@ -51,8 +58,6 @@ "Android-en bertsio zaharrago baterako diseinatuta dago aplikazio hau. Baimena ukatzen baduzu, agian aurrerantzean ez du behar bezala funtzionatuko." "Gauzatu ekintza ezezagunak" "%1$d/%2$d aplikaziok dute baimena" - "Azkenaldiko erabilera" - "Ikusi baimenen panela" "Erakutsi sistema" "Ezkutatu sistema" "Ez dago aplikaziorik" @@ -67,13 +72,17 @@ "Administratzaileak atz. planoa atzitzeko aukera desgaitu du" "Administratzaileak atzeko planoa atzitzeko aukera gaitu du" "Administratzaileak aurreko planoa atzitzeko aukera gaitu du" - "Sistemak ezarri du baimena" + + - "Beti" - "Aplikazioa erabiltzean soilik" - "Inoiz ez" + + + + + + "Kargatzen…" "Baimen guztiak" "Aplikazioaren beste gaitasun batzuk" @@ -92,22 +101,10 @@ "Aplikazioa prestatzen…" "Ezezaguna" "Panela" - - Azken erabilera: %1$s\n%2$s aldiz - Azken erabilera: %1$s\n%2$s aldiz - - - Azken erabilera: %1$s\n%2$s aldiz (%3$s atzeko planoan) - Azken erabilera: %1$s\n%2$s aldiz (%3$s atzeko planoan) - - - Azken erabilera: %1$s\n%2$s aldiz\nIraupena %3$s - Azken erabilera: %1$s\n%2$s aldiz\nIraupena: %3$s - - - Azken erabilera: %1$s\n%2$s aldiz (%3$s atzeko planoan)\nIraupena: %3$s - Azken erabilera: %1$s\n%2$s aldiz (%3$s atzeko planoan)\nIraupena: %3$s - + + + + "Edozein baimen" "Edonoiz" "Azken 7 egunetan" @@ -116,39 +113,95 @@ "Azken 15 minutuetan" "Azken minutua" "Ez da eskatu baimenik" - "Erabilera guztiak" - "Azken 7 egunetako erabilerak" - "Azken 24 orduetako erabilerak" - "Azken ordubeteko erabilerak" - "Azken 15 minutuetako erabilerak" - "Azken minutuko sarbidea" - "Inoizko baimenik erabilienak" - "Baimenik erabilienak azken 7 egunetan" - "Baimenik erabilienak azken 24 orduetan" - "Baimenik erabilienak azken ordubetean" - "Baimenik erabilienak azken 15 minutuetan" - "Baimenik erabilienak azken minutuan" - "Aplikazioak" + + + + + + + + + + + + + + + + + + + + + + + + + + + "Iragazteko irizpidea: %1$s" "Kendu iragazkia" "Iragazi honen arabera" "Iragazi baimenen arabera" + + "Baimen gehien erabili dituztenak" "Erabilienak" "Azkenak" + + + + + + "Freskatu" + "Aplikazio-baimenen erabilera" "Sarbidea: %1$s aldiz. Iraupena, guztira: %2$s. Duela %3$s erabili zen azken aldiz." "Sarbidea: %1$s aldiz. Duela %2$s erabili zen azken aldiz." "Baimendu" "Baimendu beti" - "Baimendu aplikazioa erabiltzen ari zarenean soilik" + + "Ukatu" "%1$s atzitzeko baimena" - "%1$s atzitzeko %2$s aplikazioaren baimena" - "%1$s aplikazioak %2$s atzitu du duela %3$s." - "%1$s aplikazioak ez du atzitu %2$s." - "Ikusi baimenen erabilera xehatua" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + "Azken sarbidea: %1$s" "Ez da erabili inoiz" "Baimenduta" @@ -171,8 +224,6 @@ %s segundo 1 segundo - "<b>%1$s</b> erabili nahi duzu %2$s gisa?" - "<b>%1$s</b> erabili nahi duzu (eta ez <b>%1$s</b>) %2$s gisa?" "Baimenen abisuak" "%s zure kokapena erabiltzen aritu da" "Aplikazio honek beti atzi dezake kokapena. Sakatu aldatzeko." @@ -181,19 +232,40 @@ "Ez zaio ukatu baimenik" "Ez zaio eman baimena ezein aplikaziori" "Ez zaio ukatu baimena ezein aplikaziori" - "Ireki" - "Desinstalatu" - "Behartu gelditzera" "Ezarpenak" "%s zerbitzuak gailurako sarbide osoa du" - "%s erabilerraztasun-zerbitzuk dute gailurako sarbide osoa" + + "%s zerbitzuak pantaila, egiten dituzun ekintzak eta idazten dituzun gauzak ikusi ahalko ditu, bai eta ekintzak gauzatu eta pantaila kontrolatu ere." - "Zerbitzu horiek pantaila, egiten dituzun ekintzak eta idazten dituzun gauzak ikusi ahalko dituzte, bai eta ekintzak gauzatu eta pantaila kontrolatu ere." + + + + + + + + + + + + + + + + + + + + "Aplikazio lehenetsiak" "Ez dago aplikazio lehenetsirik" + + "Lanerako aplikazio lehenetsiak" "Bat ere ez" "Ez dago aplikaziorik" + + "Aplikazio-baimen bereziak" "Ez dago aplikazio-baimen berezirik" "Ez dago aplikaziorik" @@ -207,9 +279,9 @@ "Galeria aplikazioa" "Gidatze modua ezartzeko aplikazioa" "Deiak birbideratzeko aplikazioa" - "Deiak iragazteko aplikazioa" + + "Deien aplikazio osagarria" - "Autoan islatzeko aplikazioa" "Ez ditu onartzen laneko profilak" "Oharra: gailua berrabiarazten baduzu eta pantailaren blokeoa badaukazu ezarrita, ezingo da abiarazi aplikazioa gailua desblokeatzen duzun arte." "Zure sistemak darabiltzan aplikazioei buruzko informazioa irakurri ahal izango du laguntzaileak; besteak beste, pantailan ikusgai duzun edo aplikazioetatik atzi daitekeen informazioa." @@ -220,4 +292,10 @@ "%2$s datan (%3$s) sortutako akatsen txostena kargatzeko baimena eskatzen ari da %1$s. Akatsen txostenek zure gailuari buruzkoa den edo aplikazioek erregistratu duten informazio pertsonala dute; adibidez, erabiltzaile-izenak, kokapenari buruzko datuak, gailuaren identifikatzaileak eta sareari buruzko informazioa. Informazio hori izateko fidagarriak iruditzen zaizkizun pertsona eta aplikazioekin soilik partekatu beharko zenituzke akatsen txostenak. %4$s aplikazioari akatsen txostena kargatzea baimendu nahi diozu?" "Baimendu" "Ukatu" + + + + + + diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml index 1ce6e24cb..a61c3c899 100644 --- a/res/values-fr-rCA/strings.xml +++ b/res/values-fr-rCA/strings.xml @@ -23,6 +23,10 @@ "Application non trouvée" "Refuser" "Refuser et ne plus demander" + + + + "En savoir plus" "Refuser qd même" "%1$s sur %2$s" @@ -36,7 +40,10 @@ "aucune autorisation désactivée" "Autoriser" "Autoriser tout le temps" - "Autoriser uniquement lorsque l\'appli est en cours d\'utilis." + + + + "Applications" "Autorisations des applications" "Gestionnaire des autorisations" @@ -51,8 +58,6 @@ "Cette application a été conçue pour une version antérieure d\'Android. Si vous n\'accordez pas l\'autorisation, il se peut qu\'elle ne fonctionne plus correctement." "effectuer une action inconnue" "%1$d applications autorisées sur %2$d" - "Utilisation récente" - "Affich. tabl. de bord des autor." "Afficher le système" "Masquer le système" "Aucune application" @@ -67,13 +72,17 @@ "L\'accès en arrière-plan est désactivé par l\'administrateur" "L\'accès en arrière-plan est activé par l\'administrateur" "L\'accès en avant-plan est activé par l\'administrateur" - "Autorisation définie par le système" + + - "Toujours" - "Seulement durant util. de l\'appli" - "Jamais" + + + + + + "Chargement en cours…" "Toutes les autorisations" "Autres autorisations de l\'application" @@ -92,22 +101,10 @@ "Pré-production de l\'application en cours…" "Inconnu" "Tableau de bord" - - Dernier accès : %1$s\n%2$s accès - Dernier accès : %1$s\n%2$s accès - - - Dernier accès : %1$s\n%2$s accès (%3$s en arrière-plan) - Dernier accès : %1$s\n%2$s accès (%3$s en arrière-plan) - - - Dernier accès : %1$s\n%2$s accès\nDurée : %3$s - Dernier accès : %1$s\n%2$s accès\nDurée : %3$s - - - Dernier accès : %1$s\n%2$s accès (%3$s en arrière-plan)\nDurée : %3$s - Dernier accès : %1$s\n%2$s accès (%3$s en arrière-plan)\nDurée : %3$s - + + + + "Toute autorisation" "À tout moment" "Les 7 derniers jours" @@ -116,39 +113,95 @@ "Les 15 dernières minutes" "Au cours de la dernière minute" "Aucune autoris. d\'utilisation" - "Accès en tout temps" - "Accès dans les 7 derniers jours" - "Accès dans les dernières 24 heures" - "Accès au cours de la dernière heure" - "Accès dans les 15 dernières minutes" - "Accès au cours de la dernière minute" - "Util. d\'autor. les plus populaires en tout temps" - "Util. d\'aut. les plus pop. dans les 7 dern. jours" - "Util. d\'autor. les plus pop. dans les 24 dern. h." - "Util. d\'autor. les plus popul. dans la dern. heure" - "Util. d\'autor. les plus pop. dans les 15 dern. min." - "Util. d\'autor. les plus popul. dans la dern. minute" - "Applis" + + + + + + + + + + + + + + + + + + + + + + + + + + + "Filtré par : %1$s" "Supprimer le filtre" "Filtrer par" "Filtrer par autorisation" + + "Le plus d\'autorisations" "Le plus d\'accès" "Récents" + + + + + + "Actualiser" + "Util. des autoris. de l\'appli" "Accès : %1$s fois. Durée totale : %2$s. Dernière utilisation : il y a %3$s." "Accès : %1$s fois. Dernière utilisation : il y a %2$s." "Autoriser" "Autoriser tout le temps" - "Autoriser uniquement lorsque l\'appli est en cours d\'utilis." + + "Refuser" "Autorisation %1$s" - "Accès à %1$s pour %2$s" - "%1$s a accédé à votre %2$s il y a %3$s." - "%1$s n\'a pas accédé à votre %2$s." - "Afficher les autorisations d\'utilisation détaillées" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + "Dernier accès : %1$s" "Aucun accès" "Autorisée" @@ -171,8 +224,6 @@ %s seconde %s secondes - "Utiliser <b>%1$s</b> comme %2$s?" - "Utiliser <b>%1$s</b> au lieu de <b>%1$s</b> comme %2$s?" "Rappels d\'autorisation" "%s utilise l\'accès à votre position" "Cette application peut toujours accéder à votre position. Touchez l\'écran pour modifier cela." @@ -181,19 +232,40 @@ "Aucune autorisation refusée" "Aucune application autorisée" "Aucune application refusée" - "Ouvrir" - "Désinstaller" - "Forcer l\'arrêt" "Paramètres" "%s a un accès complet à votre appareil" - "%s services d\'accessibilité ont un accès complet à votre appareil" + + "%s peut voir votre écran, vos actions et ce que vous entrez; il peut également effectuer des actions et contrôler l\'écran." - "Ces services peuvent voir votre écran, vos actions et ce que vous entrez; ils peuvent également effectuer des actions et contrôler l\'écran." + + + + + + + + + + + + + + + + + + + + "Applications par défaut" "Aucune application par défaut" + + "Par défaut pour util. profess." "Aucun" "Aucune application" + + "Accès spécial pour applis" "Aucun accès spécial pour applis" "Aucune application" @@ -207,9 +279,9 @@ "Application de galerie" "Appli tél. pour mode Voiture" "Appeler l\'application de redirection" - "Appli de filtrage des appels" + + "Application compagnon d\'appel" - "Appli de projection automobile" "Non compatible avec les profils professionnels" "Remarque : Si vous redémarrez votre appareil et que vous avez défini un verrouillage de l\'écran, cette application ne pourra pas démarrer tant que vous n\'avez pas déverrouillé votre appareil" "L\'Assistant Google pourra accéder aux données des applications en cours d\'utilisation sur votre système, y compris les données visibles à l\'écran ou accessibles au sein des applications." @@ -220,4 +292,10 @@ "L\'application %1$s souhaite téléverser un rapport de bogue créé le %2$s à %3$s sur cet appareil. Les rapports de bogue contiennent des données personnelles relatives à votre appareil ou enregistrées par des applications, comme des noms d\'utilisateur, des données de localisation, des identifiants d\'appareils et des renseignements relatifs au réseau. Ne partagez les rapports de bogue qu\'avec des personnes et des applications que vous jugez fiables. Autoriser l\'application %4$s à téléverser un rapport de bogue?" "Autoriser" "Refuser" + + + + + + diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index 3d6c4da5b..49851ba82 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -23,6 +23,10 @@ "Application non trouvée" "Refuser" "Refuser et ne plus demander" + + + + "Plus d\'infos" "Confirmer refus" "%1$s sur %2$s" @@ -36,7 +40,10 @@ "aucune désactivée" "Autoriser" "Toujours autoriser" - "Autoriser seulement quand l\'appli est en cours d\'utilisation" + + + + "Applications" "Autorisations des applications" "Gestionnaire d\'autorisations" @@ -51,8 +58,6 @@ "Cette application a été conçue pour une ancienne version d\'Android. Si vous refusez les autorisations, l\'application risque de ne plus fonctionner comme prévu." "effectuer une action inconnue" "%1$d application(s) autorisée(s) sur %2$d" - "Utilisation récente" - "Voir tableau bord autorisations" "Afficher les applications système" "Masquer les applications système" "Aucune application" @@ -67,13 +72,17 @@ "Accès en arrière-plan désactivé par l\'administrateur" "Accès en arrière-plan activé par l\'administrateur" "Accès au premier plan activé par l\'administrateur" - "Autorisation définie par le système" + + - "Toujours" - "Seulement lors utilisation appli" - "Jamais" + + + + + + "Chargement…" "Toutes les autorisations" "Autres fonctionnalités de l\'application" @@ -92,22 +101,10 @@ "Pré-production de l\'application…" "Inconnu" "Tableau de bord" - - Dernier accès : %1$s\n%2$s accès - Derniers accès : %1$s\n%2$s accès - - - Dernier accès : %1$s\n%2$s accès (%3$s en arrière-plan) - Derniers accès : %1$s\n%2$s accès (%3$s en arrière-plan) - - - Dernier accès : %1$s\n%2$s accès\nDurée : %3$s - Derniers accès : %1$s\n%2$s accès\nDurée : %3$s - - - Dernier accès : %1$s\n%2$s accès (%3$s en arrière-plan)\nDurée : %3$s - Derniers accès : %1$s\n%2$s accès (%3$s en arrière-plan)\nDurée : %3$s - + + + + "Toute autorisation" "Date indifférente" "7 derniers jours" @@ -116,39 +113,95 @@ "15 dernières minutes" "Dernière minute" "Aucune autorisation utilisée" - "Tous les accès" - "Accès au cours des sept derniers jours" - "Accès au cours des dernières 24 heures" - "Accès au cours de la dernière heure" - "Accès au cours des 15 dernières minutes" - "Accès au cours de la dernière minute" - "Autorisations les plus utilisées (toutes périodes)" - "Autorisations les plus utilisées (7 derniers jours)" - "Autorisations les plus utilisées (dernières 24 h)" - "Autorisations les plus utilisées (dernière heure)" - "Autorisations les plus utilisées (depuis 15 min)" - "Autorisations les plus utilisées (dernière minute)" - "Applis" + + + + + + + + + + + + + + + + + + + + + + + + + + + "Données filtrées par : %1$s" "Supprimer le filtre" "Filtrer par" "Filtrer par autorisation" + + "Le plus d\'autorisations" "Le plus d\'accès" "Du plus récent au plus ancien" + + + + + + "Actualiser" + "Utilisation des autorisations" "Accès : %1$s fois. Durée totale : %2$s. Dernière utilisation il y a %3$s." "Accès : %1$s fois. Dernière utilisation il y a %2$s." "Autoriser" "Toujours autoriser" - "Autoriser seulement quand l\'appli est en cours d\'utilisation" + + "Refuser" "Autorisation : %1$s" - "L\'application %2$s est autorisée à accéder à votre/vos %1$s" - "%1$s a accédé à votre/vos %2$s il y a %3$s." - "%1$s n\'a pas accédé à votre %2$s." - "Afficher l\'utilisation détaillée des autorisations" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + "Dernier accès : %1$s" "Aucun accès enregistré" "Autorisées" @@ -171,8 +224,6 @@ %s seconde %s secondes - "Utiliser <b>%1$s</b> comme %2$s ?" - "Utiliser <b>%1$s</b> au lieu de <b>%1$s</b> comme %2$s ?" "Rappels relatifs aux autorisations" "L\'application %s utilise votre position" "Cette application peut accéder en permanence à votre position. Appuyez dessus pour modifier cette autorisation." @@ -181,19 +232,40 @@ "Aucune autorisation refusée" "Cette autorisation n\'a été accordée à aucune application" "Cette autorisation n\'a été refusée à aucune application" - "Ouvrir" - "Désinstaller" - "Forcer l\'arrêt" "Paramètres" "%s bénéficie d\'un accès complet à votre appareil" - "%s services d\'accessibilité bénéficient d\'un accès complet à votre appareil" + + "%s peut voir votre écran, vos actions et ce que vous saisissez, réaliser des actions et contrôler l\'affichage." - "Ces services peuvent voir votre écran, vos actions, ce que vous saisissez, réaliser des actions et contrôler l\'affichage." + + + + + + + + + + + + + + + + + + + + "Applications par défaut" "Aucune application par défaut" + + "Par défaut pour utilisation pro" "Aucune" "Aucune application" + + "Accès spécifique des applis" "Aucun accès spécif. des applis" "Aucune application" @@ -207,9 +279,9 @@ "Application Galerie" "Appli téléphone mode Voiture" "Appli de redirection d\'appels" - "Appli de filtrage des appels" + + "Application d\'appels associée" - "Appli Projection de la voiture" "Non compatible avec le profil professionnel" "Remarque : Si vous redémarrez votre appareil et que le verrouillage de l\'écran est activé, vous ne pouvez pas lancer cette application tant que vous n\'avez pas déverrouillé votre appareil." "L\'Assistant pourra accéder aux informations relatives aux applications en cours d\'utilisation sur votre système, y compris aux informations visibles à l\'écran ou accessibles dans les applications." @@ -220,4 +292,10 @@ "L\'application %1$s souhaite transférer un rapport de bug créé le %2$s à %3$s depuis cet appareil. Les rapports de bug contiennent des informations personnelles relatives à votre appareil ou enregistrées par des applications, telles que des noms d\'utilisateur, des données de localisation, des identifiants d\'appareils et des informations relatives au réseau. Ne partagez les rapports de bug qu\'avec des personnes et des applications que vous estimez fiables. Autoriser l\'application %4$s à transférer un rapport de bug ?" "Autoriser" "Refuser" + + + + + + diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml index 7e8500380..f35af9e44 100644 --- a/res/values-hy/strings.xml +++ b/res/values-hy/strings.xml @@ -23,6 +23,10 @@ "Հավելվածը չի գտնվել" "Մերժել" "Մերժել և այլևս չհարցնել" + + + + "Մանրամասն" "Մերժել" "%1$s/%2$s" @@ -36,7 +40,10 @@ "ոչինչ չի չեղարկվել" "Թույլատրել" "Թույլատրել միշտ" - "Թույլատրել, միայն երբ հավելվածն օգտագործվում է" + + + + "Հավելվածներ" "Հավելվածների թույլտվություններ" "Թույլտվությունների կառավարիչ" @@ -51,8 +58,6 @@ "Այս հավելվածը նախատեսված է Android-ի ավելի հին տարբերակի համար: Եթե մերժեք թույլտվությունը, այն կարող է չաշխատել ինչպես հարկն է:" "կատարել անհայտ գործողություն" "Թույլատրված է %1$d հավելված՝ %2$d-ից" - "Վերջին օգտագործումը" - "Թույլտվությունների վահանակ" "Ցույց տալ համակարգի հավելվածները" "Թաքցնել համակարգի հավելվածները" "Հավելվածներ չկան" @@ -67,13 +72,17 @@ "Ադմինիստրատորն անջատել է հասանելիությունը ֆոնային ռեժիմում" "Ադմինիստրատորը միացրել է հասանելիությունը ֆոնային ռեժիմում" "Ադմինիստրատորը միացրել է հասանելիությունն ակտիվ ռեժիմում" - "Թույլտվությունը տրվել է համակարգի կողմից" + + - "Միշտ" - "Միայն հավելվածն օգտագործելիս" - "Երբեք" + + + + + + "Բեռնում…" "Բոլոր թույլտվությունները" "Էլ ինչ կարող է անել հավելվածը" @@ -92,22 +101,10 @@ "Սպասեք…" "Անհայտ" "Կառավարման վահանակ" - - Վերջին օգտագործումը՝ %1$s\n%2$s անգամ - Վերջին օգտագործումը՝ %1$s\n%2$s անգամ - - - Վերջին օգտագործումը՝ %1$s\n%2$s անգամ (%3$s անգամ ֆոնային ռեժիմում) - Վերջին օգտագործումը՝ %1$s\n%2$s անգամ (%3$s անգամ ֆոնային ռեժիմում) - - - Վերջին օգտագործումը՝ %1$s\n%2$s անգամ\nՏևողությունը՝ %3$s - Վերջին օգտագործումը՝ %1$s\n%2$s անգամ\nՏևողությունը՝ %3$s - - - Վերջին օգտագործումը՝ %1$s\n%2$s անգամ (%3$s անգամ ֆոնային ռեժիմում)\nՏևողությունը՝ %3$s - Վերջին օգտագործումը՝ %1$s\n%2$s անգամ (%3$s անգամ ֆոնային ռեժիմում)\nՏևողությունը՝ %3$s - + + + + "Բոլոր թույլտվությունները" "Ցանկացած ժամանակ" "Վերջին 7 օրում" @@ -116,39 +113,95 @@ "Վերջին 15 րոպեում" "Վերջին 1 րոպեում" "Թույլտվություններ չեն կիրառվել" - "Օգտագործված բոլոր թույլտվությունները" - "Վերջին 7 օրում օգտագործված թույլտվությունները" - "Օգտագործված թույլտվությունները վերջին 24 ժամում" - "Օգտագործված թույլտվությունները վերջին մեկ ժամում" - "Վերջին 15 րոպեում օգտագործված թույլտվությունները" - "Օգտագործված թույլտվությունները վերջին 1 րոպեում" - "Ամենաօգտագործված թույլտվությունները" - "Ամենաօգտագործված թույլտվությունները վերջին 7 օրում" - "Ամենաօգտագործված թույլտվությունները վերջին 24 ժ-ում" - "Ամենաօգտագործված թույլտվությունները վերջին 1 ժ-ում" - "Ամենաօգտագործված թույլտվությունները վերջին 15 ր-ում" - "Ամենաօգտագործված թույլտվությունները վերջին րոպեում" - "Հավելվածներ" + + + + + + + + + + + + + + + + + + + + + + + + + + + "Զտված է ըստ՝ %1$s" "Հեռացնել զտիչը" "Զտել ըստ" "Զտել ըստ թույլտվությունների" + + "Ամենաշատ օգտագործում" "Թույլտվությունների քանակ" "Վերջինները" + + + + + + "Թարմացնել" + "Թույլտվությունների օգտագործում" "Օգտագործվել է %1$s անգամ։ Ընդհանուր տևողությունը՝ %2$s։ Վերջին անգամ օգտագործվել է %3$s առաջ։" "Օգտագործվել է %1$s անգամ։ Վերջինը՝ %2$s առաջ։" "Թույլատրել" "Թույլատրել միշտ" - "Թույլատրել, միայն երբ հավելվածն օգտագործվում է" + + "Մերժել" %1$s» թույլտվություն" - %1$s» թույլտվության տրամադրում %2$s հավելվածին" - "%1$s հավելվածը ստացել է «%2$s» թույլտվությունը %3$s առաջ:" - "%1$s հավելվածին հասանելի չէ ձեր %2$sը:" - "Դիտել թույլտվությունների օգտագործման մանրամասները" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + "Վերջին օգտագործումը՝ %1$s" "Երբեք չի օգտագործվել" "Թույլատրված" @@ -171,8 +224,6 @@ %s վայրկյան %s վայրկյան - "Օգտագործե՞լ <b>%1$s</b> հավելվածը որպես ձեր %2$s:" - "Օգտագործե՞լ <b>%1$s</b> հավելվածը <b>%1$s</b> հավելվածի փոխարեն որպես ձեր %2$s:" "Հիշեցումներ թույլտվությունների մասին" %s» հավելվածն օգտագործում է ձեր տեղադրության մասին տվյալները" "Այս հավելվածին միշտ հասանելի են ձեր տեղադրության մասին տվյալները: Փոխելու համար հպեք:" @@ -181,24 +232,40 @@ "Բոլոր թույլտվությունները տրված են" "Ոչ մի հավելվածում չի գործում" "Գործում է բոլոր հավելվածներում" - "Բացել" - "Ապատեղադրել" - "Ստիպողաբար դադարեցնել" - + "Կարգավորումներ" + "%s ծառայությունն ունի ձեր սարքն օգտագործելու լրիվ թույլտվություն" + + + "%s ծառայությունը կարող է տեսնել ձեր էկրանը, գործողությունները և մուտքագրած տեքստը, ինչպես նաև կատարել գործողություններ և կառավարել էկրանը:" + + + + + + + + + + + - + - + - + - + "Կանխադրված հավելվածներ" "Կանխադրված հավելվածներ չկան" + + "Կանխադրված՝ աշխատանքի համար" "Չկա" "Հավելվածներ չկան" + + "Հատուկ հասանելիություն" "Հատուկ հասանելիություն չկա" "Հավելվածներ չկան" @@ -212,14 +279,12 @@ "Ցուցասրահ" "«Հեռախոս» մեքենայի ռեժիմի համար" "Զանգի վերահասցեավորման հավելված" - "Հավելված զանգերի զտման համար" - "Ուղեկցող հավելված զանգերի համար" - "Հեռարձակում մեքենայի էկրանին" - + + "Ուղեկցող հավելված զանգերի համար" + "Աշխատանքային պրոֆիլներ չի աջակցում" "Ուշադրություն. եթե դուք վերագործարկեք ձեր սարքը, որում սահմանված է էկրանի կողպում, այս հավելվածը չի աշխատի, մինչև չապակողպեք սարքը։" - - + "Օգնականը կկարողանա կարդալ համակարգում օգտագործվող հավելվածների մասին տվյալները, այդ թվում՝ էկրանին ցուցադրվող կամ հավելվածներից ստացվող տեղեկությունները:" "Վրիպազերծման տվյալների ուղարկում" "Ուղարկե՞լ վրիպազերծման մանրամասն տվյալները" "%1$s-ն ուզում է վերբեռնել վրիպազերծման տվյալները:" @@ -227,4 +292,10 @@ "%1$s-ը թույլտվություն է խնդրում՝ այս սարքից վրիպակների հաշվետվությունը (վերցված %2$s-ին ժամը %3$s-ին) վերբեռնելու համար: Վրիպակների հաշվետվությունները ներառում են տվյալներ ձեր սարքի մասին կամ անձնական տվյալներ, որոնք գրանցվել են հավելվածների կողմից, օրինակ՝ օգտատերերի անուններ, տեղադրության մասին տվյալներ, սարքերի ID-ներ և ցանցի մասին տեղեկություններ: Վրիպակների հաշվետվություններով կիսվեք միայն այն մարդկանց ու հավելվածների հետ, որոնց կարող եք վստահել այս տեղեկությունները: Թույլատրե՞լ %4$s-ին վերբեռնել վրիպակների հաշվետվությունը:" "Թույլատրել" "Մերժել" + + + + + + diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml index fa8333ada..7ca889ffc 100644 --- a/res/values-kk/strings.xml +++ b/res/values-kk/strings.xml @@ -23,6 +23,10 @@ "Қолданба табылмады" "Келіспеу" "Тыйым салу және қайта сұрамау" + + + + "Толығырақ" "Бәрібір рұқсат бермеу" "%1$s/%2$s" @@ -36,7 +40,10 @@ "ешқандай рұқсат өшірілмеді" "Рұқсат беру" "Әрқашан рұқсат беру" - "Қолданба пайдаланылып жатқанда ғана рұқсат беру" + + + + "Қолданбалар" "Қолданба рұқсаттары" "Рұқсат басқарушысы" @@ -51,8 +58,6 @@ "Бұл қолданба Android жүйесінің ескі нұсқасына арналған. Рұқсаттан бас тартсаңыз, бұдан былай тиісінше жұмыс істемеуі мүмкін." "белгісіз әрекетті орындау" "%1$d/%2$d қолданба рұқсатқа ие" - "Соңғы рет пайдаланылуы" - "Рұқсаттар бақылау тақтасын көру" "Жүйені көрсету" "Жүйені жасыру" "Қолданбалар жоқ" @@ -67,13 +72,17 @@ "Әкімші фондық режимде кіруге тыйым салған" "Әкімші фондық режимде кіруге рұқсат еткен" "Әкімші экрандық режимде кіруге рұқсат еткен" - "Жүйе орнатқан рұқсат" + + - "Әрқашан" - "Қолданба пайдаланылғанда ғана" - "Ешқашан" + + + + + + "Жүктелуде…" "Барлық рұқсаттар" "Басқа қолданба мүмкіндіктері" @@ -92,22 +101,10 @@ "Қолданба реттелуде…" "Белгісіз" "Бақылау тақтасы" - - Соңғы рет пайдаланылды: %1$s\n%2$s рет - Соңғы рет пайдаланылды: %1$s\n%2$s рет - - - Соңғы рет пайдаланылды: %1$s\n%2$s рет (фондық режимде %3$s рет) - Соңғы рет пайдаланылды: %1$s\n%2$s рет (фондық режимде %3$s рет) - - - Соңғы рет пайдаланылды: %1$s\n%2$s рет\nҰзақтығы: %3$s - Соңғы рет пайдаланылды: %1$s\n%2$s рет\nҰзақтығы: %3$s - - - Соңғы рет пайдаланылды: %1$s\n%2$s рет (фондық режимде %3$s рет)\nҰзақтығы: %3$s - Соңғы рет пайдаланылды: %1$s\n%2$s рет (фондық режимде %3$s рет)\nҰзақтығы: %3$s - + + + + "Кез келген рұқсат" "Кез келген уақытта" "Соңғы 7 күн" @@ -116,39 +113,95 @@ "Соңғы 15 минут" "Соңғы 1 минут" "Рұқсаттар пайдаланылмаған" - "Ең көп пайдаланылған рұқсаттар" - "Соңғы 7 күнде пайдаланылған рұқсаттар" - "Соңғы 24 сағатта пайдаланылған рұқсаттар" - "Соңғы сағатта пайдаланылған рұқсаттар" - "Соңғы 15 минутта пайдаланылған рұқсаттар" - "Соңғы 1 минутта пайдаланылған рұқсаттар" - "Ең көп пайдаланылған рұқсат" - "Соңғы 7 күнде ең көп пайдаланылған рұқсат" - "Соңғы 24 сағатта ең көп пайдаланылған рұқсат" - "Соңғы 1 сағатта ең көп пайдаланылған рұқсат" - "Соңғы 15 минутта ең көп пайдаланылған рұқсат" - "Соңғы 1 минутта ең көп пайдаланылған рұқсаттар" - "Қолданба" + + + + + + + + + + + + + + + + + + + + + + + + + + + "Сүзгі шарты: %1$s" "Сүзгіні өшіру" "Сүзгі параметрі:" "Рұқсаттар бойынша сүзу" + + "Ең көп пайдаланылған рұқсаттар" "Ең көп пайдаланылған кіру рұқсаттары" "Соңғы" + + + + + + "Жаңарту" + "Қолданба рұқсаттарын пайдалану" "Кіру рұқсаты сұралды: %1$s рет. Жалпы ұзақтығы: %2$s. Соңғы рет %3$s бұрын пайдаланылған." "Кіру рұқсаты сұралды: %1$s рет. Соңғы рет %2$s бұрын пайдаланылған." "Рұқсат беру" "Әрдайым рұқсат беру" - "Қолданба пайдаланылып жатқанда ғана рұқсат беру" + + "Келіспеу" "%1$s рұқсаты" - "%2$s қолданбасына арналған %1$s рұқсатына кіру" - "%1$s қолданбасы %2$s рұқсатына %3$s бұрын кірді." - "%1$s қолданбасы %2$s рұқсатын пайдаланбады." - "Рұқсаттардың пайдаланылуы туралы мәліметтерді көру" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + "Соңғы рет пайдаланылған уақыт: %1$s" "Ешқашан пайдаланылмады" "Берілген рұқсаттар" @@ -171,8 +224,6 @@ %s секунд 1 секунд - "<b>%1$s</b> қолданбасы %2$s рөлінде пайдаланылсын ба?" - "<b>%1$s</b> қолданбасы <b>%1$s</b> қолданбасының орнына %2$s ретінде пайдаланылсын ба?" "Рұқсат туралы еске салғыштар" "%s қолданбасы геодерегіңізді пайдаланып келді" "Бұл қолданба геодерегіңізді кез келген уақытта пайдалана алады. Өзгерту үшін түртіңіз." @@ -181,19 +232,40 @@ "Ешқандай рұқсатқа тыйым салынбады" "Ешқандай қолданбаға рұқсат берілмеді" "Ешқандай қолданбаға тыйым салынбады" - "Ашу" - "Жою" - "Қолмен тоқтату" "Параметрлер" "%s қызметі құрылғыңызды толықтай пайдалана алады" - "Арнайы мүмкіндіктер ұсынатын %s қызмет құрылғыңызды толықтай пайдалана алады" + + "%s сіздің экраныңызды, әрекеттеріңізді және енгізген деректеріңізді көре алады, әрекеттерді орындап, дисплейді басқара алады." - "Бұл қызметтер сіздің экраныңызды, әрекеттеріңізді және енгізген деректеріңізді көре алады, әрекеттерді орындап, дисплейді басқара алады." + + + + + + + + + + + + + + + + + + + + "Әдепкі қолданбалар" "Әдепкі қолданбалар жоқ" + + "Жұмыс үшін әдепкі қолданба" "Жоқ" "Қолданбалар жоқ" + + "Арнайы кіру" "Арнайы кіру мүмкіндігі жоқ" "Қолданбалар жоқ" @@ -207,9 +279,9 @@ "Галерея қолданбасы" "Көлік режиміндегі қоңырауларға арналған қолданба" "Қоңырау бағытын ауыстыру" - "Қоңырауды тексеру қолданбасы" + + "Қоңырауға арналған қосымша қолданба" - "Көлік экранына шығару" "Жұмыс профиліне қолдау көрсетпейді." "Ескертпе: Құрылғыңызды қайта қоссаңыз және экран құлыпталса, құрылғының құлпы ашылмайынша, қолданба іске қосылмайды." "Көмекші қолданба жүйеде пайдаланылып жатқан қолданбалар туралы ақпаратты, соның ішінде экранға шығатын немесе қолданбалардағы деректерді оқи алады." @@ -220,4 +292,10 @@ "%1$s қолданбасы осы құрылғыдан %2$s күні %3$s кезінде алынған қате туралы есепті жүктеп салуды сұрауда. Мұндай есептерге құрылғыңыз туралы немесе қолданбалар арқылы тіркелген жеке ақпарат (пайдаланушы аттары, геодерек, құрылғы идентификаторлары және желі туралы ақпарат) кіреді. Қате туралы есептерді тек сенімді адамдармен және қолданбалармен бөлісіңіз. %4$s қолданбасына қате туралы есепті жүктеп салуға рұқсат етілсін бе?" "Рұқсат беру" "Келіспеу" + + + + + + diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml index 4ffd879ee..1e09252ba 100644 --- a/res/values-kn/strings.xml +++ b/res/values-kn/strings.xml @@ -23,6 +23,10 @@ "ಆ್ಯಪ್ ಕಂಡುಬಂದಿಲ್ಲ" "ನಿರಾಕರಿಸಿ" "ನಿರಾಕರಿಸಿ & ಮತ್ತೊಮ್ಮೆ ಕೇಳಬೇಡಿ" + + + + "ಹೆಚ್ಚಿನ ಮಾಹಿತಿ" "ನಿರಾಕರಿಸಿ" "%2$s ರಲ್ಲಿ %1$s" @@ -36,7 +40,10 @@ "ಯಾವುದನ್ನೂ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿಲ್ಲ" "ಅನುಮತಿಸಿ" "ಎಲ್ಲಾ ಸಮಯದಲ್ಲೂ ಅನುಮತಿಸಿ" - "ಆ್ಯಪ್ ಬಳಕೆಯಲ್ಲಿದ್ದಾಗ ಮಾತ್ರ ಅನುಮತಿಸಿ" + + + + "ಆ್ಯಪ್‌ಗಳು" "ಆ್ಯಪ್ ಅನುಮತಿಗಳು" "ಅನುಮತಿ ನಿರ್ವಾಹಕರು" @@ -51,8 +58,6 @@ "ಈ ಆ್ಯಪ್‌ Android ನ ಹಳೆಯ ಆವೃತ್ತಿಗೆ ವಿನ್ಯಾಸಗೊಳಿಸಲಾಗಿತ್ತು. ಅನುಮತಿ ನಿರಾಕರಿಸುವಿಕೆ ಇನ್ನು ಮುಂದೆ ಉದ್ದೇಶಿಸಿದಂತೆ ಕಾರ್ಯನಿರ್ವಹಿಸದೆ ಇರುವುದಕ್ಕೆ ಇದು ಕಾರಣವಾಗಬಹುದು." "ಅಪರಿಚಿತ ಕ್ರಿಯೆಯನ್ನು ಮಾಡಿ" "%2$d ರಲ್ಲಿ %1$d ಆ್ಯಪ್‌ಗಳನ್ನು ಅನುಮತಿಸಲಾಗಿದೆ" - "ಇತ್ತೀ ಚಿನ ಬಳಕೆ" - "ಅನುಮತಿಗಳ ಡ್ಯಾಶ್‌ಬೋರ್ಡ್ ವೀಕ್ಷಿಸಿ" "ಸಿಸ್ಟಂ ತೋರಿಸಿ" "ಸಿಸ್ಟಂ ಮರೆಮಾಡಿ" "ಯಾವುದೇ ಆ್ಯಪ್‌ಗಳು ಇಲ್ಲ" @@ -67,13 +72,17 @@ "ಹಿನ್ನೆಲೆ ಪ್ರವೇಶವನ್ನು ನಿರ್ವಾಹಕರು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿದ್ದಾರೆ" "ಹಿನ್ನೆಲೆ ಪ್ರವೇಶವನ್ನು ನಿರ್ವಾಹಕರು ಸಕ್ರಿಯಗೊಳಿಸಿದ್ದಾರೆ" "ಮುನ್ನೆಲೆ ಪ್ರವೇಶವನ್ನು ನಿರ್ವಾಹಕರು ಸಕ್ರಿಯಗೊಳಿಸಿದ್ದಾರೆ" - "ಸಿಸ್ಟಂ ಅನುಮತಿಯನ್ನು ಹೊಂದಿಸಿದೆ" + + - "ಯಾವಾಗಲೂ" - "ಆ್ಯಪ್ ಬಳಸುವಾಗ ಮಾತ್ರ" - "ಎಂದಿಗೂ ಇಲ್ಲ" + + + + + + "ಲೋಡ್ ಆಗುತ್ತಿದೆ..." "ಎಲ್ಲಾ ಅನುಮತಿಗಳು" "ಇತರ ಆ್ಯಪ್‌ ಸಾಮರ್ಥ್ಯಗಳು" @@ -92,22 +101,10 @@ "ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಲು ಸಿದ್ಧವಿರುವ ಆ್ಯಪ್…" "ಅಪರಿಚಿತ" "ಡ್ಯಾಶ್‌ಬೋರ್ಡ್" - - ಕೊನೆಯ ಪ್ರವೇಶ: %1$s\n%2$s ಪ್ರವೇಶ - ಕೊನೆಯ ಪ್ರವೇಶ: %1$s\n%2$s ಪ್ರವೇಶ - - - ಕೊನೆಯ ಪ್ರವೇಶ: %1$s\n%2$s ಪ್ರವೇಶ (%3$sಹಿನ್ನೆಲೆಯಲ್ಲಿ) - ಕೊನೆಯ ಪ್ರವೇಶ: %1$s\n%2$s ಪ್ರವೇಶ (%3$sಹಿನ್ನೆಲೆಯಲ್ಲಿ) - - - ಕೊನೆಯ ಪ್ರವೇಶ: %1$s\n%2$s ಪ್ರವೇಶ\nಸಮಯ: %3$s - ಕೊನೆಯ ಪ್ರವೇಶ: %1$s\n%2$s ಪ್ರವೇಶ\nಸಮಯ: %3$s - - - ಕೊನೆಯ ಪ್ರವೇಶ: %1$s\n%2$s ಪ್ರವೇಶ (%3$sಹಿನ್ನೆಲೆಯಲ್ಲಿ)\nಸಮಯದಲ್ಲಿ: %3$s - ಕೊನೆಯ ಪ್ರವೇಶ: %1$s\n%2$s ಪ್ರವೇಶ (%3$sಹಿನ್ನೆಲೆಯಲ್ಲಿ)\nಸಮಯದಲ್ಲಿ: %3$s - + + + + "ಯಾವುದೇ ಅನುಮತಿ" "ಯಾವುದಾದರೂ ಸಮಯದಲ್ಲಿ" "ಕಳೆದ 7 ದಿನಗಳು" @@ -116,39 +113,95 @@ "ಹಿಂದಿನ 15 ನಿಮಿಷಗಳು" "ಕಳೆದ 1 ನಿಮಿಷ" "ಅನುಮತಿಯ ಬಳಕೆಗಳು ಇಲ್ಲ" - "ಯಾವಾಗ ಬೇಕಾದರೂ ಪ್ರವೇಶಿಸಿ" - "ಕಳೆದ 7 ದಿನಗಳಲ್ಲಿ ಪ್ರವೇಶ" - "ಕಳೆದ 24 ಗಂಟೆಗಳಲ್ಲಿ ಪ್ರವೇಶ" - "ಕಳೆದ ಒಂದು ಗಂಟೆಯಲ್ಲಿ ಪ್ರವೇಶ" - "ಕಳೆದ 15 ನಿಮಿಷಗಳಲ್ಲಿ ಪ್ರವೇಶ" - "ಕಳೆದ 1 ನಿಮಿಷದಲ್ಲಿ ಪ್ರವೇಶ" - "ಯಾವುದೇ ಸಮಯದಲ್ಲಿ ಪ್ರಮುಖ ಅನುಮತಿಯ ಬಳಕೆ" - "ಕಳೆದ 7 ದಿನಗಳಲ್ಲಿ ಪ್ರಮುಖ ಅನುಮತಿಯ ಬಳಕೆ" - "ಕಳೆದ 24 ಗಂಟೆಗಳಲ್ಲಿ ಪ್ರಮುಖ ಅನುಮತಿಯ ಬಳಕೆ" - "ಕಳೆದ 1 ಗಂಟೆಯಲ್ಲಿ ಪ್ರಮುಖ ಅನುಮತಿಯ ಬಳಕೆ" - "ಕಳೆದ 15 ನಿಮಿಷಗಳಲ್ಲಿ ಪ್ರಮುಖ ಅನುಮತಿಯ ಬಳಕೆ" - "ಕಳೆದ 1 ನಿಮಿಷದಲ್ಲಿ ಪ್ರಮುಖ ಅನುಮತಿಯ ಬಳಕೆ" - "ಆ್ಯಪ್‌ಗಳು" + + + + + + + + + + + + + + + + + + + + + + + + + + + "ಈ ಆಧಾರದ ಮೇಲೆ ಫಿಲ್ಟರ್ ಮಾಡಲಾಗಿದೆ: %1$s" "ಫಿಲ್ಟರ್ ತೆಗೆದುಹಾಕಿ" "ಈ ಪ್ರಕಾರ ಫಿಲ್ಟರ್" "ಅನುಮತಿಗಳ ಮೂಲಕ ಫಿಲ್ಟರ್ ಮಾಡಿ" + + "ಹೆಚ್ಚಿನ ಅನುಮತಿಗಳು" "ಹೆಚ್ಚಿನ ಪ್ರವೇಶಗಳು" "ಇತ್ತೀಚಿನವು" + + + + + + "ರಿಫ್ರೆಶ್ ಮಾಡಿ" + "ಆ್ಯಪ್‌ ಅನುಮತಿಗಳ ಬಳಕೆ" "ಪ್ರವೇಶ: %1$s ಬಾರಿ. ಒಟ್ಟು ಅವಧಿ: %2$s. %3$s ಸಮಯದ ಹಿಂದೆ ಕೊನೆಯದಾಗಿ ಬಳಸಲಾಗಿದೆ." "ಪ್ರವೇಶ: %1$s ಬಾರಿ. %2$s ಸಮಯದ ಹಿಂದೆ ಕೊನೆಯದಾಗಿ ಬಳಸಲಾಗಿದೆ." "ಅನುಮತಿಸಿ" "ಎಲ್ಲಾ ಸಮಯದಲ್ಲೂ ಅನುಮತಿಸಿ" - "ಆ್ಯಪ್ ಬಳಕೆಯಲ್ಲಿದ್ದಾಗ ಮಾತ್ರ ಅನುಮತಿಸಿ" + + "ನಿರಾಕರಿಸಿ" "%1$s ಅನುಮತಿ" - "%2$s ಆ್ಯಪ್‌ಗಾಗಿ %1$s ಪ್ರವೇಶ" - "%1$s ಆ್ಯಪ್ ನಿಮ್ಮ %2$s ಅನ್ನು %3$s ಹಿಂದೆ ಪ್ರವೇಶಿಸಿದೆ." - "%1$s ನಿಮ್ಮ %2$s ಅನ್ನು ಪ್ರವೇಶಿಸಿಲ್ಲ." - "ವಿವರವಾದ ಅನುಮತಿಗಳ ಬಳಕೆಯನ್ನು ವೀಕ್ಷಿಸಿ" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + "ಕೊನೆಯ ಪ್ರವೇಶ:%1$s" "ಎಂದಿಗೂ ಪ್ರವೇಶಿಸಿಲ್ಲ" "ಅನುಮತಿಸಲಾಗಿದೆ" @@ -171,8 +224,6 @@ %s ಸೆಕೆಂಡುಗಳು %s ಸೆಕೆಂಡುಗಳು - "<b>%1$s</b> ಅನ್ನು ನಿಮ್ಮ %2$s ಎಂದು ಬಳಸುವುದೇ?" - "<b>%1$s</b> ಅನ್ನು <b>%1$s</b> ರ ಬದಲಿಗೆ ನಿಮ್ಮ %2$s ಎಂದು ಬಳಸುವುದೇ?" "ಅನುಮತಿ ಜ್ಞಾಪನೆಗಳು" "%s ನಿಮ್ಮ ಸ್ಥಳವನ್ನು ಬಳಸುತ್ತಿದೆ" "ಈ ಆ್ಯಪ್‌ ಯಾವಾಗಲೂ ನಿಮ್ಮ ಸ್ಥಳವನ್ನು ಪ್ರವೇಶಿಸಬಹುದು. ಬದಲಾಯಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ." @@ -181,24 +232,40 @@ "ಯಾವುದೇ ಅನುಮತಿಗಳನ್ನು ನಿರಾಕರಿಸಲಾಗಿಲ್ಲ" "ಯಾವುದೇ ಆ್ಯಪ್‌ಗಳನ್ನು ಅನುಮತಿಸಲಾಗಿಲ್ಲ" "ಯಾವುದೇ ಆ್ಯಪ್‌ಗಳನ್ನು ನಿರಾಕರಿಸಲಾಗಿಲ್ಲ" - "ತೆರೆ" - "ಅನ್‌ಇನ್‌ಸ್ಟಾಲ್" - "ಬಲವಂತವಾಗಿ ನಿಲ್ಲಿಸಿ" - + "ಸೆಟ್ಟಿಂಗ್‌ಗಳು" + "%s ಸೇವೆಯು ನಿಮ್ಮ ಸಾಧನಕ್ಕೆ ಸಂಪೂರ್ಣ ಪ್ರವೇಶವನ್ನು ಹೊಂದಿದೆ" + + + "%s ಸೇವೆಯು ನಿಮ್ಮ ಸ್ಕ್ರೀನ್, ಕ್ರಿಯೆಗಳು ಮತ್ತು ಇನ್‌ಪುಟ್‌ಗಳು, ಕೆಲಸ ನಿರ್ವಹಣೆ ಕ್ರಿಯೆಗಳು ಮತ್ತು ಡಿಸ್‌ಪ್ಲೇ ನಿಯಂತ್ರಣವನ್ನು ವೀಕ್ಷಿಸಬಹುದು." + + + + + + + + + + + - + - + - + - + "ಡೀಫಾಲ್ಟ್ ಆ್ಯಪ್‌ಗಳು" "ಯಾವುದೇ ಡೀಫಾಲ್ಟ್‌ ಆ್ಯಪ್‌ಗಳಿಲ್ಲ" + + "ಕೆಲಸದ ಕುರಿತಾದ ಡೀಫಾಲ್ಟ್ ಆ್ಯಪ್" "ಯಾವುದೂ ಬೇಡ" "ಯಾವುದೇ ಆ್ಯಪ್‌ಗಳು ಇಲ್ಲ" + + "ಆ್ಯಪ್‌ಗೆ ವಿಶೇಷ ಪ್ರವೇಶ" "ಆ್ಯಪ್‌ಗೆ ವಿಶೇಷ ಪ್ರವೇಶವಿಲ್ಲ" "ಯಾವುದೇ ಆ್ಯಪ್‌ಗಳು ಇಲ್ಲ" @@ -212,14 +279,12 @@ "ಗ್ಯಾಲರಿ ಆ್ಯಪ್‌" "ಕಾರ್‌ ಮೋಡ್‌ ಫೋನ್‌ ಆ್ಯಪ್" "ಕರೆ ಮರುನಿರ್ದೇಶನ ಆ್ಯಪ್‌" - "ಕರೆ ಸ್ಕ್ರೀನಿಂಗ್ ಆ್ಯಪ್" - "ಕರೆ ಕಂಪ್ಯಾನಿಯನ್ ಆ್ಯಪ್" - "ಕಾರ್ ಪ್ರೊಜೆಕ್ಷನ್ ಆ್ಯಪ್‌" - + + "ಕರೆ ಕಂಪ್ಯಾನಿಯನ್ ಆ್ಯಪ್" + "ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್ ಅನ್ನು ಬೆಂಬಲಿಸುವುದಿಲ್ಲ" "ಗಮನಿಸಿ: ನೀವು ನಿಮ್ಮ ಸಾಧನವನ್ನು ಮರುಪ್ರಾರಂಭಿಸಿದಲ್ಲಿ ಮತ್ತು ಪರದೆಯ ಲಾಕ್‌ ಹೊಂದಿದ್ದರೆ, ನಿಮ್ಮ ಸಾಧನವನ್ನು ಅನ್‌ಲಾಕ್‌ ಮಾಡುವವರೆಗೂ ಈ ಆ್ಯಪ್‌ ಅನ್ನು ಪ್ರಾರಂಭಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ" - - + "ನಿಮ್ಮ ಸ್ಕ್ರೀನ್‌ನಲ್ಲಿ ಗೋಚರಿಸುವ ಅಥವಾ ಆ್ಯಪ್‌ಗಳಲ್ಲಿಯೇ ಪ್ರವೇಶಿಸಬಹುದಾದಂತಹ ಮಾಹಿತಿ ಸೇರಿದಂತೆ, ನಿಮ್ಮ ಸಿಸ್ಟಂನಲ್ಲಿ ಬಳಕೆಯಲ್ಲಿರುವ ಆ್ಯಪ್‌ಗಳ ಕುರಿತ ಮಾಹಿತಿಯನ್ನು ಓದಲು ಅಸಿಸ್ಟೆಂಟ್‌ಗೆ ಸಾಧ್ಯವಾಗುತ್ತದೆ." "ಡೀಬಗ್ ಮಾಡುವಿಕೆ ಡೇಟಾವನ್ನು ಹಂಚಿಕೊಳ್ಳಿ" "ವಿವರವಾದ ಡೀಬಗ್ ಮಾಡುವಿಕೆಯ ಡೇಟಾವನ್ನು ಹಂಚಿಕೊಳ್ಳಬೇಕೆ?" "%1$s ಆ್ಯಪ್, ಡೀಬಗ್ ಮಾಡುವಿಕೆಯ ಮಾಹಿತಿಯನ್ನು ಅಪ್‌ಲೋಡ್ ಮಾಡಲು ಬಯಸುತ್ತದೆ." @@ -227,4 +292,10 @@ "%2$s ದಿನಾಂಕದಂದು %3$s ಸಮಯಕ್ಕೆ ತೆಗೆದುಕೊಂಡ ಬಗ್ ವರದಿಯನ್ನು ಈ ಸಾಧನದಿಂದ ಅಪ್‌ಲೋಡ್ ಮಾಡುವಂತೆ %1$s ಆ್ಯಪ್ ವಿನಂತಿಸುತ್ತಿದೆ. ಬಗ್ ವರದಿಗಳು, ನಿಮ್ಮ ಸಾಧನ ಅಥವಾ ಆ್ಯಪ್‌ಗಳ ಮೂಲಕ ಲಾಗ್ ಮಾಡಿದ ವೈಯಕ್ತಿಕ ಮಾಹಿತಿಯನ್ನು, ಉದಾಹರಣೆಗೆ ಬಳಕೆದಾರರ ಹೆಸರುಗಳು, ಸ್ಥಳದ ಡೇಟಾ, ಸಾಧನ ಗುರುತಿಸುವಿಕೆಗಳು ಮತ್ತು ನೆಟ್‌ವರ್ಕ್‌ ಮಾಹಿತಿಯನ್ನು ಒಳಗೊಂಡಿದೆ. ಈ ಮಾಹಿತಿ ಒಳಗೊಂಡಂತೆ, ನೀವು ನಂಬುವ ಜನರು ಮತ್ತು ಆ್ಯಪ್‌ಗಳ ಜೊತೆಗೆ ಮಾತ್ರ ಬಗ್ ವರದಿಗಳನ್ನು ಹಂಚಿಕೊಳ್ಳಿ. ಬಗ್ ವರದಿಯನ್ನು ಅಪ್‌ಲೋಡ್‌ ಮಾಡಲು %4$s ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸುವುದೇ?" "ಅನುಮತಿಸಿ" "ನಿರಾಕರಿಸಿ" + + + + + + diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml index 76ebe09aa..20e3f94ee 100644 --- a/res/values-mr/strings.xml +++ b/res/values-mr/strings.xml @@ -23,6 +23,10 @@ "अ‍ॅप आढळले नाही" "नकार द्या" "नकार द्या आणि पुन्हा विचारू नका" + + + + "अधिक माहिती" "तरीही नकार द्या" "%1$s पैकी %2$s" @@ -36,7 +40,10 @@ "कोणत्याही बंद केल्या नाहीत" "परवानगी द्या" "प्रत्येक वेळी अनुमती द्या" - "फक्त अ‍ॅप वापरत असताना अनुमती द्या" + + + + "अॅप्स" "अ‍ॅप परवानग्या" "परवानगी व्यवस्थापक" @@ -51,8 +58,6 @@ "हे अ‍ॅप Android च्या जुन्या आवृत्तीसाठी डीझाइन करण्यात आले होते. परवानगी नाकारल्यामुळे ते यापुढे अपेक्षित असल्याप्रमाणे कार्य करणार नाही." "अज्ञात क्रिया करा" "%1$d पैकी %2$d अ‍ॅप्सना परवानगी दिली" - "अलीकडील वापर" - "परवानग्या डॅशबोर्ड पाहा" "सिस्टम दर्शवा" "सिस्टम लपवा" "कोणतेही अॅप्स नाहीत" @@ -67,13 +72,17 @@ "प्रशासकाने बॅकग्राउंड अॅक्सेस बंद केला आहे" "प्रशासकाने बॅकग्राउंड अॅक्सेस सुरू केला आहे" "प्रशासकाने फोरग्राउंड अॅक्सेस सुरू केला आहे" - "सिस्टमद्वारे परवानगी सेट केली आहे" + + - "नेहमी" - "फक्त अ‍ॅप वापरत असताना" - "कधीही नाही" + + + + + + "लोड होत आहे…" "सर्व परवानग्या" "अन्य अ‍ॅप क्षमता" @@ -92,22 +101,10 @@ "अ‍ॅप सुरुवातीच्या स्थितीत आहे…" "अज्ञात" "डॅशबोर्ड" - - शेवटचा अ‍ॅक्सेस: %1$s\n%2$s अ‍ॅक्सेस - शेवटचा अ‍ॅक्सेस: %1$s\n%2$s अ‍ॅक्सेस - - - शेवटचा अ‍ॅक्सेस: %1$s\n%2$s अ‍ॅक्सेस (बॅकग्राउंडमध्ये %3$s) - शेवटचा अ‍ॅक्सेस: %1$s\n%2$s अ‍ॅक्सेस (बॅकग्राउंडमध्ये %3$s) - - - शेवटचा अ‍ॅक्सेस: %1$s\n%2$s अ‍ॅक्सेस\nकालावधी: %3$s - शेवटचा अ‍ॅक्सेस: %1$s\n%2$s अ‍ॅक्सेस\nकालावधी: %3$s - - - शेवटचा अ‍ॅक्सेस: %1$s\n%2$s अ‍ॅक्सेस (बॅकग्राउंडमध्ये %3$s)\n कालावधी: %3$s - शेवटचा अ‍ॅक्सेस: %1$s\n%2$s अ‍ॅक्सेस (बॅकग्राउंडमध्ये %3$s)\n कालावधी: %3$s - + + + + "कोणतीही परवानगी" "कधीही" "शेवटचे सात दिवस" @@ -116,39 +113,95 @@ "शेवटची १५ मिनिटे" "अंतिम एक मिनिट" "वापराची परवानगी नाही" - "कोणत्याही वेळी अ‍ॅक्सेस" - "मागील सात दिवसांतील अ‍ॅक्सेस" - "मागील २४ तासांतील अॅक्सेस" - "मागील तासातील अ‍ॅक्सेस" - "मागील १५ मिनिटांतील अ‍ॅक्सेस" - "मागील एक मिनिटातील अ‍ॅक्सेस" - "कोणत्याही वेळी टॉप परवानगी वापर" - "मागील सात दिवसांतील टॉप परवानगी वापर" - "मागील २४ तासांतील टॉप परवानगी वापर" - "मागील एक तासातील टॉप परवानगी वापर" - "मागील १५ मिनिटांतील टॉप परवानगी वापर" - "मागील एक मिनिटामधील टॉप परवानगी वापर" - "अॅप्स" + + + + + + + + + + + + + + + + + + + + + + + + + + + "यानुसार फिल्टर केले: %1$s" "फिल्टर काढून टाका" "यानुसार फिल्टर करा" "परवानग्यांनुसार फिल्टर करा" + + "सर्वाधिक परवानग्या" "सर्वाधिक अॅक्सेस" "नुकतेच" + + + + + + "रिफ्रेश करा" + "अ‍ॅप परवानग्यांचा वापर" "अॅक्सेस करा: %1$s वेळा. एकूण कालावधी: %2$s. %3$s पूर्वी शेवटचे वापरले." "अॅक्सेस करा: %1$s वेळा. %2$s पूर्वी शेवटचे वापरले." "अनुमती द्या" "सर्व वेळी अनुमती द्या" - "फक्त अ‍ॅप वापरत असताना अनुमती द्या" + + "नकार द्या" "%1$s परवानगी" - "%1$s साठी %2$s अॅक्सेस केली" - "%1$s ने तुमची %2$s %3$s पूर्वी अॅक्सेस केली." - "%1$s ला तुमच्या %2$sचा अॅक्सेस दिलेला नाही." - "परवानग्यांचा वापर तपशीलवार पाहा" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + "शेवटचा अ‍ॅक्सेस: %1$s" "कधीही अ‍ॅक्सेस केलेले नाही" "अनुमती असलेले" @@ -171,8 +224,6 @@ %s सेकंद %s सेकंद - "तुमचे %2$s म्हणून <b>%1$s</b> वापरायचे आहे का?" - "तुमचे %2$s म्हणून <b>%1$s</b> ऐवजी <b>%1$s</b> वापरायचे आहे का?" "परवानगी रिमाइंडर" "%s तुमचे स्थान वापरत आहे" "हे अ‍ॅप नेहमी तुमचे स्थान अॅक्सेस करू शकते. बदलण्यासाठी टॅप करा." @@ -181,19 +232,40 @@ "कोणत्याही परवानग्या नाकारल्या नाहीत" "कोणत्याही अॅप्सला अनुमती नाही" "कोणतीही अॅप्स नाकारली नाहीत" - "उघडा" - "अनइंस्टॉल करा" - "सक्तीने थांबवा" "सेटिंग्ज" "%s ला तुमच्या डिव्हाइसचा पुर्ण अ‍ॅक्सेस आहे" - "%s अ‍ॅक्सेसिबिलिटी सेवांना तुमच्या डिव्हाइसचा पुर्ण अ‍ॅक्सेस आहे" + + "%s तुमची स्क्रीन, क्रिया आणि इनपुट, करत असलेल्या क्रिया पाहू शकेल आणि डिस्प्ले नियंत्रित करू शकेल." - "या सेवा तुमची स्क्रीन, क्रिया आणि इनपुट पाहू शकतात, क्रिया करू शकतात आणि डिस्प्ले नियंत्रित करू शकतात." + + + + + + + + + + + + + + + + + + + + "डीफॉल्ट अ‍ॅप्स" "कोणतीही डीफॉल्‍ट अ‍ॅप्स नाहीत" + + "कार्यासाठी डीफॉल्ट" "काहीही नाही" "अॅप्स नाहीत" + + "विशेष अॅप अॅक्सेस" "कोणताही विशेष अॅप अॅक्सेस नाही" "कोणतीही अॅप्स नाहीत" @@ -207,9 +279,9 @@ "गॅलरी अ‍ॅप" "कार मोड फोन अ‍ॅप" "कॉल रीडिरेक्‍ट करणारे अ‍ॅप" - "स्क्रीनिंग अ‍ॅपला कॉल करा" + + "सहयोगी अ‍ॅपला कॉल करा" - "कार प्रोजेक्शन अ‍ॅप" "कार्य प्रोफाइलला सपोर्ट नाही" "टीप: तुम्ही तुमचे डिव्हाइस रीस्टार्ट केल्यास आणि स्क्रीन लॉक सेट केले असल्यास, तुम्ही तुमचे डिव्हाइस अनलॉक करेपर्यंत हे अ‍ॅप सुरू होऊ शकत नाही." "तुमच्या स्क्रीनवर दृश्‍यमान असलेल्या माहितीच्या किंवा अ‍ॅप्समध्ये अ‍ॅक्सेस करता येणाऱ्या माहितीच्या समावेशासह असिस्टंट तुमच्या सिस्टिममध्ये वापरल्या जाणाऱ्या अ‍ॅप्सबद्दलची माहिती वाचू शकेल." @@ -220,4 +292,10 @@ "%1$s %2$s रोजी %3$s वाजता घेतलेल्या या डिव्हाइसमधून बग रिपोर्ट अपलोड करण्याची विनंती करत आहे. बग रिपोर्टमध्ये तुमच्या डिव्हाइसविषयीच्या किंवा अ‍ॅप्सने लॉग केलेल्या वैयक्तिक माहितीचा समावेश अहे, उदाहरणार्थ वापरकर्ता नावे, स्थान डेटा, डिव्हाइस आयडेंटिफायर आणि नेटवर्क माहिती. या माहितीसह फक्त तुम्हाला विश्वास असलेल्या लोकांसह आणि अ‍ॅप्ससह बग रिपोर्ट शेअर करा. %4$s ला बग रिपोर्ट अपलोड करण्याची अनुमती द्यायची?" "अनुमती द्या" "नकार द्या" + + + + + + diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml index fbc2fe03c..b55a0db64 100644 --- a/res/values-pt-rPT/strings.xml +++ b/res/values-pt-rPT/strings.xml @@ -23,6 +23,10 @@ "Aplicação não encontrada" "Recusar" "Recusar e não perguntar novamente" + + + + "Mais informação" "Recus. na mesma" "%1$s de %2$s" @@ -36,7 +40,10 @@ "nenhuma desativada" "Permitir" "Permitir sempre" - "Permitir apenas enquanto a aplicação está a ser utilizada" + + + + "Aplicações" "Autorizações da aplicação" "Gestor de autorizações" @@ -51,8 +58,6 @@ "Esta aplicação foi concebida para uma versão mais antiga do Android. Recusar a autorização pode fazer com que deixe de funcionar como pretendido." "executar uma ação desconhecida" "%1$d de %2$d aplicações autorizadas" - "Utilização recente" - "Ver Painel de autorizações" "Mostrar sistema" "Ocultar sistema" "Sem aplicações" @@ -67,13 +72,17 @@ "Acesso em segundo plano desativado pelo administrador" "Acesso em segundo plano ativado pelo administrador" "Acesso em primeiro plano ativado pelo administrador" - "Autorização definida pelo sistema" + + - "Sempre" - "Apenas ao utilizar a aplicação" - "Nunca" + + + + + + "A carregar…" "Todas as autorizações" "Outras capacidades de aplicações" @@ -92,22 +101,10 @@ "A preparar a aplicação…" "Desconhecido" "Painel" - - Último acesso: %1$s\n%2$s acessos - Último acesso: %1$s\n%2$s acesso - - - Último acesso: %1$s\n%2$s acessos (%3$s em segundo plano) - Último acesso: %1$s\n%2$s acesso (%3$s em segundo plano) - - - Último acesso: %1$s\n%2$s acessos\nDuração: %3$s - Último acesso: %1$s\n%2$s acesso\nDuração: %3$s - - - Último acesso: %1$s\n%2$s acessos %3$s em segundo plano)\nDuração: %3$s - Último acesso: %1$s\n%2$s acesso (%3$s em segundo plano)\nDuração: %3$s - + + + + "Qualquer autorização" "Em qualquer altura" "Últimos 7 dias" @@ -116,39 +113,95 @@ "Últimos 15 minutos" "Último minuto" "Autorizações não utilizadas" - "Acesso em qualquer altura" - "Acesso nos últimos 7 dias" - "Acesso nas últimas 24 horas" - "Acesso na última hora" - "Acesso nos últimos 15 minutos" - "Acesso no último minuto" - "Utiliz. das princ. autorizações em qualquer altura" - "Utiliz. das princ. autorizações nos últimos 7 dias" - "Utiliz. das princ. autorizações nas últ. 24 horas" - "Utiliz. das principais autorizações na última hora" - "Utiliz. das princ. autorizações nos últ. 15 min" - "Utiliz. das principais autorizações no último min" - "Aplicações" + + + + + + + + + + + + + + + + + + + + + + + + + + + "Filtrado por: %1$s" "Remover filtro" "Filtrar por" "Filtrar por autorizações" + + "Maioria de autorizações" "Maioria de acessos" "Recentes" + + + + + + "Atualizar" + "Utiliz. de autoriz. da app" "Acesso: %1$s vezes. Duração total: %2$s. Última utilização há %3$s." "Acesso: %1$s vezes. Última utilização há %2$s." "Permitir" "Permitir sempre" - "Permitir apenas enquanto a aplicação está a ser utilizada" + + "Recusar" "Autorização para o(a) %1$s" - "Acesso ao(à) %1$s para a aplicação %2$s." - "A aplicação %1$s acedeu ao(à) %2$s%3$s." - "A aplicação %1$s não acedeu à sua %2$s." - "Ver utilização de autorizações detalhada" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + "Último acesso: %1$s" "Nunca acedida" "Permitidas" @@ -171,8 +224,6 @@ %s segundos 1 segundo - "Pretende utilizar <b>%1$s</b> como %2$s?" - "Pretende utilizar <b>%1$s</b> em vez de <b>%1$s</b> como %2$s?" "Lembretes de autorização" "A aplicação %s tem estado a utilizar a sua localização" "Esta aplicação consegue aceder sempre à sua localização. Toque para alterar." @@ -181,19 +232,40 @@ "Nenhuma autorização recusada." "Nenhuma aplicação permitida." "Nenhuma aplicação recusada." - "Abrir" - "Desinstalar" - "Forçar paragem" "Definições" "O serviço %s tem acesso total ao seu dispositivo" - "%s serviços de acessibilidade têm acesso total ao seu dispositivo" + + "O serviço %s pode ver o seu ecrã, as ações e as entradas, efetuar ações e controlar o ecrã." - "Estes serviços podem ver o ecrã, as ações e as entradas, efetuar ações e controlar o ecrã." + + + + + + + + + + + + + + + + + + + + "Aplicações predefinidas" "Sem aplicações predefinidas" + + "Predefinição para o trabalho" "Nenhuma" "Sem aplicações" + + "Acesso especial a aplicações" "Sem acesso especial a aplic." "Sem aplicações" @@ -203,13 +275,13 @@ "Aplicação de SMS" "Aplicação de emergência" "Aplicação Página inicial" - "Aplicação de música" + "App de música" "Aplicação de galeria" "Aplic. Telefone modo automóvel" "Aplic. de redirec. de chamadas" - "Aplic. de filtro de chamadas" + + "Aplic. associada de chamadas" - "Aplicação Car Projection" "Não suporta o perfil de trabalho." "Nota: se reiniciar o dispositivo e tiver um bloqueio de ecrã definido, só é possível iniciar esta aplicação quando o dispositivo for desbloqueado." "O assistente pode ler informações sobre aplicações em utilização no seu sistema, incluindo informações visíveis no ecrã ou acessíveis nas aplicações." @@ -220,4 +292,10 @@ "A aplicação %1$s está a solicitar o carregamento de um relatório de erro a partir deste dispositivo realizado a %2$s à(s) %3$s. Os relatórios de erros incluem informações pessoais acerca do seu dispositivo ou registadas por aplicações, por exemplo, nomes de utilizador, dados de localização, identificadores do dispositivo e informações da rede. Apenas partilhe relatórios de erros com pessoas e aplicações nas quais confia. Permite que a aplicação %4$s carregue um relatório de erro?" "Permitir" "Recusar" + + + + + + diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml index c787d2c12..af44f4f1f 100644 --- a/res/values-sk/strings.xml +++ b/res/values-sk/strings.xml @@ -23,6 +23,10 @@ "Aplikácia sa nenašla" "Zamietnuť" "Zamietnuť a už sa nepýtať" + + + + "Ďalšie info" "Zamietnuť" "%1$s%2$s" @@ -36,7 +40,10 @@ "žiadne nie sú zakázané" "Povoliť" "Povoliť po celý čas" - "Povoliť iba počas používania aplikácie" + + + + "Aplikácie" "Povolenia aplikácií" "Správca povolení" @@ -53,8 +60,6 @@ "Táto aplikácia bola navrhnutá pre staršiu verziu Androidu. Odmietnutie povolenia môže spôsobiť, že nebude optimálne fungovať." "umožňuje vykonať neznámu akciu" "Povolené: %1$d%2$d aplikácií" - "Nedávne využitie" - "Zobraziť hlavný panel povolení" "Zobraziť systémové" "Skryť systémové" "Žiadne aplikácie" @@ -69,13 +74,17 @@ "Prístup na pozadí bol zakázaný správcom" "Prístup na pozadí bol povolený správcom" "Prístup na popredí bol povolený správcom" - "Povolenie nastavené systémom" + + - "Vždy" - "Iba počas používania aplikácie" - "Nikdy" + + + + + + "Načítava sa…" "Všetky povolenia" "Ďalšie možnosti aplikácie" @@ -94,30 +103,10 @@ "Aplikácia je zavádzaná po etapách…" "Neznáme" "Hlavný panel" - - Posledný prístup: %1$s\n%2$s prístupy - Posledný prístup: %1$s\n%2$s accesses - Posledný prístup: %1$s\n%2$s prístupov - Posledný prístup: %1$s\n%2$s prístup - - - Posledný prístup: %1$s\n%2$s prístupy (%3$s na pozadí) - Posledný prístup: %1$s\n%2$s accesses (%3$s in background) - Posledný prístup: %1$s\n%2$s prístupov (%3$s na pozadí) - Posledný prístup: %1$s\n%2$s prístup (%3$s na pozadí) - - - Posledný prístup: %1$s\n%2$s prístupy\nTrvanie: %3$s - Posledný prístup: %1$s\n%2$s accesses\nDuration: %3$s - Posledný prístup: %1$s\n%2$s prístupov\nTrvanie: %3$s - Posledný prístup: %1$s\n%2$s prístup\nTrvanie: %3$s - - - Posledný prístup: %1$s\n%2$s prístupy (%3$s na pozadí)\nTrvanie: %3$s - Posledný prístup: %1$s\n%2$s accesses (%3$s in background)\nDuration: %3$s - Posledný prístup: %1$s\n%2$s prístupov (%3$s na pozadí)\nTrvanie: %3$s - Posledný prístup: %1$s\n%2$s prístup (%3$s na pozadí)\nTrvanie: %3$s - + + + + "Všetky povolenia" "Kedykoľvek" "Posledných 7 dní" @@ -126,39 +115,95 @@ "Posledných 15 minút" "Posledná minúta" "Žiadne využitie povolení" - "Prístup v celom období" - "Prístup v posledných 7 dňoch" - "Prístup v posledných 24 hodinách" - "Prístup v poslednej hodine" - "Prístup v posledných 15 minútach" - "Prístup v poslednej minúte" - "Najviac používané povolenia za celé obdobie" - "Najviac používané povolenia za posledných 7 dní" - "Najviac používané povolenia za posledných 24 hodín" - "Najviac používané povolenia za poslednú hodinu" - "Najviac používané povolenia za posledných 15 minút" - "Najviac používané povolenia za poslednú minútu" - "Aplikácie" + + + + + + + + + + + + + + + + + + + + + + + + + + + "Filtrované podľa: %1$s" "Odstrániť filter" "Filtrovať podľa" "Filtrovať podľa povolení" + + "Najviac povolení" "Najviac prístupov" "Nedávne" + + + + + + "Obnoviť" + "Využitie povolení aplikácie" "Prístup: %1$s‑krát. Celkové trvanie: %2$s. Naposledy použité pred %3$s." "Prístup: %1$s‑krát. Naposledy použité pred %2$s." "Povoliť" "Povoliť po celý čas" - "Povoliť iba počas používania aplikácie" + + "Odmietnuť" "Povolenie %1$s" - "Prístup k %1$s pre %2$s" - "Aplikácia %1$s použila %2$s pred %3$s." - "%1$s nemôže používať povolenie %2$s." - "Zobraziť podrobné údaje o využití povolení" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + "Posledný prístup: %1$s" "Prístup sa nikdy neuskutočnil" "Povolené" @@ -189,8 +234,6 @@ %s sekúnd 1 sekunda - "Chcete aplikáciu <b>%1$s</b> použiť ako %2$s?" - "Chcete použiť aplikáciu <b>%1$s</b> (namiesto aplikácie <b>%1$s</b>) ako %2$s?" "Pripomenutia povolení" "%s používa vašu polohu" "Táto aplikácia má neobmedzený prístup k polohe. Klepnutím to zmeníte." @@ -199,19 +242,40 @@ "Žiadne odmietnuté povolenia" "Žiadne povolené aplikácie" "Žiadne odmietnuté aplikácie" - "Otvoriť" - "Odinštalovať" - "Vynútiť zastavenie" "Nastavenia" "%s má úplný prístup do vášho zariadenia" - "Služby dostupnosti s úplným prístupom do vášho zariadenia: %s" + + "%s si môže zobraziť vašu obrazovku, akcie a vstupy, vykonávať akcie a ovládať obrazovku." - "Tieto služby si môžu zobraziť vašu obrazovku, akcie a vstupy, vykonávať akcie a ovládať obrazovku." + + + + + + + + + + + + + + + + + + + + "Predvolené aplikácie" "Žiadne predvolené aplikácie" + + "Predvolené na prácu" "Žiadna" "Žiadne aplikácie" + + "Špeciálny prístup aplikácií" "Žiadny špeciálny prístup aplikácií" "Žiadne aplikácie" @@ -225,9 +289,9 @@ "Aplikácia Galéria" "Aplikácia režimu v aute pre telefóny" "Aplikácia na presmer. hovorov" - "Aplikácia na filtrovanie hovorov" + + "Sprievodná aplikácia na hovory" - "Aplikácia na projekciu v aute" "Nepodporuje pracovný profil" "Poznámka: Ak reštartujete zariadenie a máte nastavenú zámku obrazovky, táto aplikácia sa spustí až po odomknutí zariadenia." "Pomocník bude môcť čítať informácie o aplikáciách používaných vo vašom systéme vrátane údajov viditeľných na obrazovke alebo prístupných v aplikáciách." @@ -238,4 +302,10 @@ "%1$s žiada o nahranie hlásenia chyby z tohto zariadenia vytvoreného %2$s%3$s. Hlásenia chýb zahŕňajú osobné údaje o zariadení alebo osobné údaje zapísané aplikáciami, napríklad používateľské mená, údaje o polohe, identifikátory zariadenia a informácie o sieti. Hlásenia chýb zdieľajte iba s dôveryhodnými osobami a aplikáciami. Chcete povoliť aplikácii %4$s nahrať hlásenie chyby?" "Povoliť" "Odmietnuť" + + + + + + diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml index 9ef0b3030..5b70800da 100644 --- a/res/values-ta/strings.xml +++ b/res/values-ta/strings.xml @@ -23,6 +23,10 @@ "ஆப்ஸ் இல்லை" "நிராகரி" "நிராகரி, மீண்டும் கேட்காதே" + + + + "மேலும் தகவல்" "நிராகரி" "%1$s / %2$s" @@ -36,7 +40,10 @@ "எதுவும் முடக்கப்படவில்லை" "அனுமதி" "அனைத்து நேரங்களிலும் அனுமதி" - "ஆப்ஸ் உபயோகத்தில் இருக்கும்போது மட்டும் அனுமதி" + + + + "ஆப்ஸ்" "ஆப்ஸ் அனுமதிகள்" "அனுமதி நிர்வாகம்" @@ -51,8 +58,6 @@ "Androidன் பழைய பதிப்புக்காக இந்த ஆப்ஸ் வடிவமைக்கப்பட்டது. அனுமதியை மறுத்தால் அது சரியாகச் செயல்படாமல் போகலாம்." "அறியப்படாத செயலைச் செய்யும்" "அனுமதிக்கப்பட்ட ஆப்ஸ்: %1$d/%2$d" - "சமீபத்திய உபயோகம்" - "அனுமதிகள் டாஷ்போர்டைக் காட்டு" "சிஸ்டம் ஆப்ஸைக் காட்டு" "சிஸ்டம் ஆப்ஸை மறை" "எந்த ஆப்ஸிற்கும் தேவையில்லை" @@ -67,13 +72,17 @@ "\'பின்புல அணுகலை\' நிர்வாகி முடக்கியுள்ளார்" "\'பின்புல அணுகலை’ நிர்வாகி இயக்கியுள்ளார்" "\'முன்புல அணுகலை\' நிர்வாகி இயக்கியுள்ளார்" - "சிஸ்டத்தால் அமைக்கப்பட்டுள்ள அனுமதி" + + - "எப்போதும்" - "ஆப்ஸ் பயன்பாட்டில் மட்டும்" - "ஒருபோதும் வேண்டாம்" + + + + + + "ஏற்றுகிறது…" "அனைத்து அனுமதிகளும்" "ஆப்ஸிற்கான பிற அனுமதிகள்" @@ -92,22 +101,10 @@ "ஆப்ஸ் தயாராகிறது…" "தெரியாதது" "டாஷ்போர்டு" - - கடைசியாகப் பயன்படுத்தியது: %1$s\nபயன்படுத்தியவை: %2$s - கடைசியாகப் பயன்படுத்தியது: %1$s\nபயன்படுத்தியது: %2$s - - - கடைசியாகப் பயன்படுத்தியது: %1$s\nபயன்படுத்தியவை: %2$s(பின்னணியில் பயன்படுத்தியவை: %3$s) - கடைசியாகப் பயன்படுத்தியது: %1$s\nபயன்படுத்தியது: %2$s(பின்னணியில் பயன்படுத்தியது: %3$s) - - - கடைசியாகப் பயன்படுத்தியது: %1$s\nபயன்படுத்தியவை: %2$s\nகால அளவு: %3$s - கடைசியாகப் பயன்படுத்தியது: %1$s\nபயன்படுத்தியது: %2$s\nகால அளவு: %3$s - - - கடைசியாகப் பயன்படுத்தியது: %1$s\nபயன்படுத்தியவை: %2$s (பின்னணியில் பயன்படுத்தியவை:%3$s)\nகால அளவு: %3$s - கடைசியாகப் பயன்படுத்தியது: %1$s\nபயன்படுத்தியது: %2$s(பின்னணியில் பயன்படுத்தியது: %3$s)\nகால அளவு: %3$s - + + + + "அனுமதி எதுவாயினும்" "எந்த நேரமும்" "கடந்த 7 நாட்கள்" @@ -116,39 +113,95 @@ "கடந்த 15 நிமிடங்கள்" "கடந்த 1 நிமிடத்தில்" "உபயோகிக்கப்படாத அனுமதிகள்" - "இதுவரையிலான அணுகல்" - "கடந்த 7 நாட்களில் அணுகல்" - "கடந்த 24 மணிநேரத்தில் அணுகல்" - "கடந்த 1 மணிநேரத்தில் அணுகல்" - "கடந்த 15 நிமிடத்தில் அணுகல்" - "கடந்த 1 நிமிடத்தில் பயன்படுத்தியது" - "இதுவரையில் உபயோகித்த அதிகபட்ச அனுமதி" - "கடந்த 7 நாட்களில் உபயோகித்த அதிகபட்ச அனுமதி" - "கடந்த 24 மணிநேரத்தில் உபயோகித்த அதிகபட்ச அனுமதி" - "கடந்த 1 மணிநேரத்தில் உபயோகித்த அதிகபட்ச அனுமதி" - "கடந்த 15 நிமிடத்தில் உபயோகித்த அதிகபட்ச அனுமதி" - "கடந்த 1 நிமிடத்தில் உபயோகித்த அதிகபட்ச அனுமதி" - "ஆப்ஸ்" + + + + + + + + + + + + + + + + + + + + + + + + + + + "இதன்படி வடிகட்டப்பட்டது: %1$s" "வடிப்பானை அகற்று" "இதன்படி வடிகட்டுதல்" "அனுமதிகளின்படி வடிகட்டு" + + "அதிகப்படியான அனுமதிகள்" "அதிகப்படியான அணுகல்கள்" "சமீபத்தியவை" + + + + + + "புதுப்பி" + "ஆப்ஸ் அனுமதிகளை உபயோகித்தல்" "அணுகல்: %1$s முறை. மொத்தக் கால அளவு: %2$s. கடைசியாகப் பயன்படுத்தியது %3$s முன்பு." "அணுகல்: %1$s முறை. கடைசியாகப் பயன்படுத்தியது %2$s முன்பு." "அனுமதி" "அனைத்து நேரங்களிலும் அனுமதி" - "ஆப்ஸ் உபயோகத்தில் இருக்கும்போது மட்டும் அனுமதி" + + "நிராகரி" "%1$s என்பதற்கான அனுமதி" - "%2$s ஆப்ஸிற்கான %1$s அணுகல்" - "%3$s நேரத்திற்கு முன்பு %1$s ஆப்ஸ் உங்கள் %2$sஐ அணுகியது." - "%1$s உங்கள் %2$s அனுமதியைப் பயன்படுத்தவில்லை." - "அனுமதிகளின் உபயோகம் தொடர்பான விவரங்களைக் காட்டு" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + "கடைசியாகப் பயன்படுத்தியது: %1$s" "பயன்படுத்தியதில்லை" "அனுமதிக்கப்பட்டவை" @@ -171,8 +224,6 @@ %s விநாடிகள் 1 விநாடி - "<b>%1$s</b> என்பதை %2$s ஆகப் பயன்படுத்தவா?" - "<b>%1$s</b> என்பதை <b>%1$s</b> என்பதற்குப் பதிலாக %2$s ஆகப் பயன்படுத்தவா?" "அனுமதிக்கான நினைவூட்டல்கள்" "%s உங்கள் இருப்பிடத்தைப் பயன்படுத்துகிறது" "எப்பொழுதும் உங்கள் இருப்பிடத்தை இந்த ஆப்ஸால் பயன்படுத்த இயலும். மாற்றத் தட்டவும்." @@ -181,19 +232,40 @@ "எந்த அனுமதிகளும் மறுக்கப்படவில்லை" "எந்த ஆப்ஸும் அனுமதிக்கப்படவில்லை" "எந்த ஆப்ஸுக்கும் அனுமதி மறுக்கப்படவில்லை" - "திற" - "நிறுவல் நீக்கு" - "உடனே நிறுத்து" "அமைப்புகள்" "உங்கள் சாதனத்திற்கான முழு அணுகல் %s சேவைக்கு உள்ளது" - "உங்கள் சாதனத்திற்கான முழு அணுகல் %s அணுகல்தன்மை சேவைகளுக்கு உள்ளது" + + "உங்கள் திரை, செயல்கள் மற்றும் உள்ளீடுகளைப் பார்க்கவும், செயல்களை நிறைவேற்றவும், காட்சியைக் கட்டுப்படுத்தவும் %s சேவையால் இயலும்." - "உங்கள் திரை, செயல்கள் மற்றும் உள்ளீடுகளைப் பார்க்கவும், செயல்களை நிறைவேற்றவும், காட்சியைக் கட்டுப்படுத்தவும் இந்தச் சேவைகளால் இயலும்." + + + + + + + + + + + + + + + + + + + + "இயல்புநிலை ஆப்ஸ்" "இயல்புநிலை ஆப்ஸ் இல்லை" + + "பணிக்கான இயல்பு நிலை ஆப்ஸ்" "ஏதுமில்லை" "ஆப்ஸ் இல்லை" + + "ஆப்ஸிற்கான சிறப்பு அணுகல்" "ஆப்ஸிற்கு சிறப்பு அணுகல் இல்லை" "ஆப்ஸ் இல்லை" @@ -207,9 +279,9 @@ "கேலரி ஆப்ஸ்" "கார் மோடுக்கான மொபைல் ஆப்ஸ்" "அழைப்பைத் திருப்பிவிடும் ஆப்ஸ்" - "அழைப்புத் திரை ஆப்ஸ்" + + "அழைப்புக்கான கம்பேனியன் ஆப்ஸ்" - "கார் காட்சிப்படுத்தல் ஆப்ஸ்" "பணிக் கணக்கிற்கான ஆதரவு இதில் இல்லை" "கவனத்திற்கு: திரைப் பூட்டு அமைக்கப்பட்டிருக்கும் நிலையில் உங்கள் மொபைலை மீண்டும் தொடங்கினால் அன்லாக் செய்யப்படும்வரை இந்த ஆப்ஸ் இயங்காது." "திரையில் தெரியும் தகவல் அல்லது ஆப்ஸிற்குள் அணுகக்கூடிய தகவல் உட்பட உங்கள் சிஸ்டத்தில் செயல்பாட்டிலுள்ள ஆப்ஸ் பற்றிய தகவல்களை அசிஸ்டண்ட்டால் படிக்க இயலும்." @@ -220,4 +292,10 @@ "இந்தச் சாதனத்திலிருந்து %2$s அன்று %3$s மணிக்கு எடுக்கப்பட்ட பிழை அறிக்கையைப் பதிவேற்றுமாறு %1$s கோருகிறது. இதில் பயனர் பெயர்கள், இருப்பிடத் தரவு, சாதன அடையாளங்காட்டிகள் மற்றும் நெட்வொர்க் தகவல்கள் போன்ற உங்கள் சாதனம் அல்லது உள்நுழைந்துள்ள ஆப்ஸ் பற்றிய தனிப்பட்ட தகவல்களும் உள்ளடங்கும். இந்தத் தகவல்களுடனான பிழை அறிக்கைகளை நம்பகமானவர்களுடனும் ஆப்ஸுடனும் மட்டுமே பகிரவும். பிழை அறிக்கையைப் பதிவேற்ற %4$s ஆப்ஸை அனுமதிக்கவா?" "அனுமதி" "நிராகரி" + + + + + + diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml index 6af8b3db1..9c95f4dfc 100644 --- a/res/values-vi/strings.xml +++ b/res/values-vi/strings.xml @@ -23,6 +23,10 @@ "Không tìm thấy ứng dụng" "Từ chối" "Từ chối và không hỏi lại" + + + + "Thông tin khác" "Vẫn từ chối" "%1$s/%2$s" @@ -36,7 +40,10 @@ "chưa tắt quyền nào" "Cho phép" "Luôn cho phép" - "Chỉ cho phép khi đang sử dụng ứng dụng" + + + + "Ứng dụng" "Quyền ứng dụng" "Người quản lý quyền" @@ -51,8 +58,6 @@ "Ứng dụng này được thiết kế cho các phiên bản Android cũ hơn. Nếu bạn từ chối quyền, thì ứng dụng này có thể không còn hoạt động như dự kiến." "thực hiện hành động không xác định" "Đã cho phép %1$d/%2$d ứng dụng" - "Mức sử dụng gần đây" - "Xem trang tổng quan về quyền" "Hiển thị hệ thống" "Ẩn hệ thống" "Không có ứng dụng" @@ -67,13 +72,17 @@ "Quản trị viên đã tắt quyền truy cập khi ở nền sau" "Quản trị viên đã bật quyền truy cập khi ở nền sau" "Quản trị viên đã bật quyền truy cập khi ở nền trước" - "Quyền do hệ thống đặt" + + - "Luôn luôn" - "Chỉ khi dùng ứng dụng" - "Không bao giờ" + + + + + + "Đang tải…" "Tất cả các quyền" "Các khả năng khác của ứng dụng" @@ -92,22 +101,10 @@ "Đang thử nghiệm ứng dụng…" "Không xác định" "Trang tổng quan" - - Lần truy cập gần đây nhất: %1$s\n%2$s lần truy cập - Lần truy cập gần đây nhất: %1$s\n%2$s lần truy cập - - - Lần truy cập gần đây nhất: %1$s\n%2$s lần truy cập (%3$s trong nền) - Lần truy cập gần đây nhất: %1$s\n%2$s lần truy cập (%3$s trong nền) - - - Lần truy cập gần đây nhất: %1$s\n%2$s lần truy cập\nThời lượng: %3$s - Lần truy cập gần đây nhất: %1$s\n%2$s lần truy cập\nThời lượng: %3$s - - - Lần truy cập gần đây nhất: %1$s\n%2$s lần truy cập (%3$s trong nền)\nThời lượng: %3$s - Lần truy cập gần đây nhất: %1$s\n%2$s lần truy cập (%3$s trong nền)\nThời lượng: %3$s - + + + + "Mọi quyền" "Mọi lúc" "7 ngày qua" @@ -116,39 +113,95 @@ "15 phút trước" "1 phút qua" "Không sử dụng quyền" - "Truy cập bất cứ lúc nào" - "Truy cập trong 7 ngày qua" - "Truy cập trong 24 giờ qua" - "Truy cập trong giờ qua" - "Truy cập trong 15 phút qua" - "Truy cập trong 1 phút qua" - "Cách sử dụng quyền phổ biến nhất bất cứ lúc nào" - "Cách sử dụng quyền phổ biến nhất trong 7 ngày qua" - "Cách sử dụng quyền phổ biến nhất trong 24 giờ qua" - "Cách sử dụng quyền phổ biến nhất trong 1 giờ qua" - "Cách sử dụng quyền phổ biến nhất trong 15 phút qua" - "Cách sử dụng quyền phổ biến nhất trong 1 phút qua" - "Ứng dụng" + + + + + + + + + + + + + + + + + + + + + + + + + + + "Đã lọc bởi: %1$s" "Xóa bộ lọc" "Lọc theo" "Lọc theo quyền" + + "Nhiều quyền nhất" "Nhiều lần truy cập nhất" "Gần đây" + + + + + + "Làm mới" + "Sử dụng quyền ứng dụng" "Truy cập: %1$s lần. Tổng thời gian: %2$s. Sử dụng lần gần đây nhất vào %3$s trước." "Truy cập: %1$s lần. Sử dụng lần gần đây nhất vào %2$s trước." "Cho phép" "Luôn cho phép" - "Chỉ cho phép khi đang sử dụng ứng dụng" + + "Từ chối" "Quyền %1$s" - "Quyền truy cập vào %1$s của %2$s" - "%1$s đã truy cập vào %2$s %3$s trước." - "%1$s chưa truy cập vào %2$s của bạn." - "Xem mức sử dụng quyền chi tiết" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + "Lần truy cập gần đây nhất: %1$s" "Chưa bao giờ truy cập" "Được phép" @@ -171,8 +224,6 @@ %s giây 1 giây - "Bạn có muốn dùng <b>%1$s</b> làm %2$s của mình không?" - "Bạn có muốn dùng <b>%1$s</b> thay vì <b>%1$s</b> làm %2$s của mình không?" "Lời nhắc về quyền" "%s đã sử dụng thông tin vị trí của bạn" "Ứng dụng này luôn có thể truy cập vào thông tin vị trí của bạn. Hãy nhấn để thay đổi." @@ -181,24 +232,40 @@ "Chưa từ chối quyền nào" "Chưa cho phép ứng dụng nào" "Chưa từ chối ứng dụng nào" - "Mở" - "Gỡ cài đặt" - "Buộc dừng" - + "Cài đặt" + "%s có quyền truy cập đầy đủ vào thiết bị của bạn" + + + "%s có thể xem màn hình, hành động và dữ liệu nhập của bạn cũng như thực hiện hành động và điều khiển màn hình." + + + + + + + + + + + - + - + - + - + "Ứng dụng mặc định" "Không có ứng dụng mặc định" + + "Ứng dụng mặc định cho công việc" "Không có" "Không có ứng dụng nào" + + "Quyền truy cập đặc biệt" "Không có quyền truy cập đặc biệt" "Không có ứng dụng" @@ -212,14 +279,12 @@ "Ứng dụng thư viện" "Ứng dụng điện thoại cho chế độ ô tô" "Ứng dụng chuyển hướng cuộc gọi" - "Ứng dụng sàng lọc cuộc gọi" - "Ứng dụng đồng hành cuộc gọi" - "Ứng dụng Chiếu trên ô tô" - + + "Ứng dụng đồng hành cuộc gọi" + "Không hỗ trợ hồ sơ công việc" "Lưu ý: Nếu bạn khởi động lại thiết bị và đặt khóa màn hình, thì ứng dụng này sẽ không thể khởi động cho đến khi bạn mở khóa thiết bị." - - + "Trợ lý sẽ có thể đọc thông tin về ứng dụng mà bạn đang dùng trên hệ thống, bao gồm cả thông tin hiển thị trên màn hình hoặc thông tin có thể truy cập trong ứng dụng." "Chia sẻ dữ liệu gỡ lỗi" "Bạn muốn chia sẻ dữ liệu gỡ lỗi chi tiết?" "%1$s muốn tải thông tin gỡ lỗi lên." @@ -227,4 +292,10 @@ "%1$s đang yêu cầu tải lên từ thiết bị này một báo cáo lỗi được thực hiện vào %2$s lúc %3$s. Báo cáo lỗi bao gồm thông tin cá nhân về thiết bị của bạn hoặc do ứng dụng ghi nhật ký, ví dụ như tên người dùng, dữ liệu vị trí, giá trị nhận dạng thiết bị và thông tin mạng. Chỉ chia sẻ báo cáo lỗi với người và ứng dụng bạn tin cậy đối với thông tin này. Bạn muốn cho phép %4$s tải báo cáo lỗi lên?" "Cho phép" "Từ chối" + + + + + + -- GitLab From 4efef4dc0672822143d92118646f421a57a92ff2 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Mon, 25 Mar 2019 08:12:06 -0700 Subject: [PATCH 483/701] Tweak Permissions Hub strings. Fixes: 129144537 Test: View both strings. Change-Id: Id6b42dbef4c19e1999f158789cfe52b26185a207 --- res/values/strings.xml | 4 ++-- .../ui/handheld/PermissionControlPreference.java | 11 ++++------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 1d6ed9d35..35eb65f75 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -263,10 +263,10 @@ Dashboard - Last access: %1$s <font color="#0f9d58">(while the app was in use)</font> + Last access: %1$s\nLast accessed while app was in use - Last access: %1$s (in the background) + Last access: %1$s\nLast accessed in the background Any permission diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionControlPreference.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionControlPreference.java index 9d438202b..78a01c927 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionControlPreference.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionControlPreference.java @@ -19,7 +19,6 @@ package com.android.packageinstaller.permission.ui.handheld; import android.content.Context; import android.content.Intent; import android.graphics.drawable.Drawable; -import android.text.Html; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; @@ -123,13 +122,11 @@ public class PermissionControlPreference extends Preference { */ public void setUsageSummary(@NonNull GroupUsage groupUsage, @NonNull String accessTimeStr) { if (groupUsage.getLastAccessForegroundTime() >= groupUsage.getLastAccessBackgroundTime()) { - setSummary(Html.fromHtml( - mContext.getString(R.string.permission_usage_summary_foreground, - accessTimeStr))); + setSummary(mContext.getString(R.string.permission_usage_summary_foreground, + accessTimeStr)); } else { - setSummary(Html.fromHtml( - mContext.getString(R.string.permission_usage_summary_background, - accessTimeStr))); + setSummary(mContext.getString(R.string.permission_usage_summary_background, + accessTimeStr)); } } -- GitLab From c22c4d4d4806c8d735290d561497db760862c4e0 Mon Sep 17 00:00:00 2001 From: Anton Hansson Date: Fri, 22 Mar 2019 16:04:45 +0000 Subject: [PATCH 484/701] Pretend to be Settings for location notifications This looks up the Settings app name via the public activity intent and adds that to the notification header. Also requires we request the SUBSTITUTE_NOTIFICATION_APP_NAME permission. Bug: 128608303 Test: trigger notification, look at sender app ('Settings' on a Google build) Change-Id: Idb52ca36c837f6a012a2e13fe380f107f7a70130 --- AndroidManifest.xml | 1 + .../service/LocationAccessCheck.java | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 793e4c52b..b42d3a3fa 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -37,6 +37,7 @@ + diff --git a/src/com/android/packageinstaller/permission/service/LocationAccessCheck.java b/src/com/android/packageinstaller/permission/service/LocationAccessCheck.java index a4006f79a..a5c3ffcf6 100644 --- a/src/com/android/packageinstaller/permission/service/LocationAccessCheck.java +++ b/src/com/android/packageinstaller/permission/service/LocationAccessCheck.java @@ -73,12 +73,14 @@ import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.drawable.Drawable; import android.location.LocationManager; import android.net.Uri; import android.os.AsyncTask; +import android.os.Bundle; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; @@ -554,6 +556,8 @@ public class LocationAccessCheck { clickIntent.putExtra(EXTRA_PACKAGE_NAME, pkgName); clickIntent.putExtra(EXTRA_USER, user); + CharSequence appName = getNotificationAppName(); + Notification.Builder b = (new Notification.Builder(mContext, PERMISSION_REMINDER_CHANNEL_ID)) .setContentTitle(mContext.getString( @@ -570,6 +574,13 @@ public class LocationAccessCheck { FLAG_ONE_SHOT | FLAG_UPDATE_CURRENT)) .setContentIntent(getBroadcast(mContext, 0, clickIntent, FLAG_ONE_SHOT | FLAG_UPDATE_CURRENT)); + + if (appName != null) { + Bundle extras = new Bundle(); + extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME, appName.toString()); + b.addExtras(extras); + } + notificationManager.notify(pkgName, LOCATION_ACCESS_CHECK_NOTIFICATION_ID, b.build()); if (DEBUG) Log.i(LOG_TAG, "Notified " + pkgName); @@ -578,6 +589,17 @@ public class LocationAccessCheck { currentTimeMillis()).apply(); } + @Nullable + private CharSequence getNotificationAppName() { + // We pretend we're the Settings app sending the notification, so figure out its name. + Intent openSettingsIntent = new Intent(Settings.ACTION_SETTINGS); + ResolveInfo resolveInfo = mPackageManager.resolveActivity(openSettingsIntent, 0); + if (resolveInfo == null) { + return null; + } + return mPackageManager.getApplicationLabel(resolveInfo.activityInfo.applicationInfo); + } + /** * Get currently shown notification. We only ever show one notification per profile group. * -- GitLab From 85e7e33c930e0abf0967fb32743e24a0055bdff4 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Mon, 25 Mar 2019 10:05:24 -0700 Subject: [PATCH 485/701] Improve ongoing usage dialog. Fix a bug where the permission icons were not vertically centered. Migrate the logic from the Activity to a Fragment to support TV. Fix an issue where if you opened the dialog, followed it to another screen, went to home, then re-opened the dialog, you would see the old screen under it. Test: Open dialog, click various options, re-open dialog. Change-Id: I2dd1d195d32f8eb141d52c54d14f677f3d0b62bf --- AndroidManifest.xml | 1 + res/values/styles.xml | 4 +- .../ui/ReviewOngoingUsageActivity.java | 184 ++------------ .../handheld/ReviewOngoingUsageFragment.java | 230 ++++++++++++++++++ 4 files changed, 252 insertions(+), 167 deletions(-) create mode 100644 src/com/android/packageinstaller/permission/ui/handheld/ReviewOngoingUsageFragment.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 793e4c52b..d55441058 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -145,6 +145,7 @@ diff --git a/res/values/styles.xml b/res/values/styles.xml index d8da231dd..406bbe882 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -483,8 +483,8 @@ wrap_content match_parent horizontal - end - end|center_vertical + end|center_vertical + end gone diff --git a/src/com/android/packageinstaller/permission/ui/ReviewOngoingUsageActivity.java b/src/com/android/packageinstaller/permission/ui/ReviewOngoingUsageActivity.java index 3486d8492..cba0a24b2 100644 --- a/src/com/android/packageinstaller/permission/ui/ReviewOngoingUsageActivity.java +++ b/src/com/android/packageinstaller/permission/ui/ReviewOngoingUsageActivity.java @@ -16,40 +16,17 @@ package com.android.packageinstaller.permission.ui; -import static android.Manifest.permission_group.CAMERA; -import static android.Manifest.permission_group.LOCATION; -import static android.Manifest.permission_group.MICROPHONE; +import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS; -import android.app.AlertDialog; import android.content.Intent; import android.os.Bundle; -import android.os.UserHandle; -import android.provider.Settings; -import android.util.ArraySet; -import android.util.Pair; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.TextView; +import android.view.MenuItem; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import androidx.fragment.app.FragmentActivity; -import com.android.packageinstaller.permission.model.AppPermissionUsage; -import com.android.packageinstaller.permission.model.AppPermissionUsage.GroupUsage; -import com.android.packageinstaller.permission.model.PermissionApps; -import com.android.packageinstaller.permission.model.PermissionApps.PermissionApp; -import com.android.packageinstaller.permission.model.PermissionUsages; -import com.android.packageinstaller.permission.utils.Utils; -import com.android.permissioncontroller.R; - -import java.text.Collator; -import java.time.Instant; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.TimeUnit; +import com.android.packageinstaller.DeviceUtils; +import com.android.packageinstaller.permission.ui.handheld.ReviewOngoingUsageFragment; /** * A dialog listing the currently uses of camera, microphone, and location. @@ -59,154 +36,31 @@ public final class ReviewOngoingUsageActivity extends FragmentActivity { // Number of milliseconds in the past to look for accesses if nothing was specified. private static final long DEFAULT_MILLIS = 5000; - private @NonNull PermissionUsages mPermissionUsages; - private @Nullable AlertDialog mDialog; - private long mStartTime; - @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - if (!Utils.isPermissionsHubEnabled()) { - return; - } + getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS); long numMillis = getIntent().getLongExtra(Intent.EXTRA_DURATION_MILLIS, DEFAULT_MILLIS); - - mPermissionUsages = new PermissionUsages(this); - mStartTime = Math.max(System.currentTimeMillis() - numMillis, Instant.EPOCH.toEpochMilli()); - mPermissionUsages.load(null, new String[] { CAMERA, LOCATION, MICROPHONE }, mStartTime, - Long.MAX_VALUE, PermissionUsages.USAGE_FLAG_LAST, getLoaderManager(), false, false, - this::onPermissionUsagesLoaded, false); - } - - private void onPermissionUsagesLoaded() { - List appPermissionUsages = mPermissionUsages.getUsages(); - - List>> usages = new ArrayList<>(); - ArrayList permApps = new ArrayList<>(); - int numApps = appPermissionUsages.size(); - for (int appNum = 0; appNum < numApps; appNum++) { - AppPermissionUsage appUsage = appPermissionUsages.get(appNum); - - List usedGroups = new ArrayList<>(); - List appGroups = appUsage.getGroupUsages(); - int numGroups = appGroups.size(); - for (int groupNum = 0; groupNum < numGroups; groupNum++) { - GroupUsage groupUsage = appGroups.get(groupNum); - String groupName = groupUsage.getGroup().getName(); - - if (groupUsage.getLastAccessTime() < mStartTime && !groupUsage.isRunning()) { - continue; - } - if (!Utils.isGroupOrBgGroupUserSensitive(groupUsage.getGroup())) { - continue; - } - - usedGroups.add(appGroups.get(groupNum)); - } - - if (!usedGroups.isEmpty()) { - usages.add(Pair.create(appUsage, usedGroups)); - permApps.add(appUsage.getApp()); - } - } - - if (usages.isEmpty()) { - finish(); - return; - } - - new PermissionApps.AppDataLoader(this, () -> showDialog(usages)) - .execute(permApps.toArray(new PermissionApps.PermissionApp[permApps.size()])); - } - - private void showDialog(@NonNull List>> usages) { - mDialog = new AlertDialog.Builder(this) - .setView(createDialogView(usages)) - .setPositiveButton(R.string.ongoing_usage_dialog_ok, null) - .setNeutralButton(R.string.ongoing_usage_dialog_open_settings, (dialog, which) -> - startActivity(new Intent(Settings.ACTION_PRIVACY_SETTINGS).putExtra( - Intent.EXTRA_DURATION_MILLIS, TimeUnit.MINUTES.toMillis(1)))) - .setOnDismissListener((dialog) -> finish()) - .create(); - mDialog.show(); + getSupportFragmentManager().beginTransaction().replace(android.R.id.content, + ReviewOngoingUsageFragment.newInstance(numMillis)).commit(); } - private @NonNull View createDialogView( - @NonNull List>> usages) { - LayoutInflater inflater = LayoutInflater.from(this); - View contentView = inflater.inflate(R.layout.ongoing_usage_dialog_content, null); - ViewGroup appsList = contentView.requireViewById(R.id.items_container); - - // Compute all of the permission group labels that were used. - ArraySet usedGroups = new ArraySet<>(); - int numUsages = usages.size(); - for (int usageNum = 0; usageNum < numUsages; usageNum++) { - List groups = usages.get(usageNum).second; - int numGroups = groups.size(); - for (int groupNum = 0; groupNum < numGroups; groupNum++) { - usedGroups.add(groups.get(groupNum).getGroup().getLabel().toString().toLowerCase()); - } - } - - // Add the layout for each app. - for (int usageNum = 0; usageNum < numUsages; usageNum++) { - Pair> usage = usages.get(usageNum); - PermissionApp app = usage.first.getApp(); - List groups = usage.second; - - View itemView = inflater.inflate(R.layout.ongoing_usage_dialog_item, appsList, false); - - ((TextView) itemView.requireViewById(R.id.app_name)).setText(app.getLabel()); - ((ImageView) itemView.requireViewById(R.id.app_icon)).setImageDrawable(app.getIcon()); - // Add the icons for the groups this app used as long as multiple groups were used by - // some app. - if (usedGroups.size() > 1) { - ViewGroup iconFrame = itemView.requireViewById(R.id.icons); - int numGroups = usages.get(usageNum).second.size(); - for (int groupNum = 0; groupNum < numGroups; groupNum++) { - ViewGroup group = (ViewGroup) inflater.inflate(R.layout.image_view, null); - ((ImageView) group.requireViewById(R.id.icon)).setImageDrawable( - Utils.applyTint(this, groups.get(groupNum).getGroup().getIconResId(), - android.R.attr.colorControlNormal)); - iconFrame.addView(group); + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + // in automotive mode, there's no system wide back button, so need to add that + if (DeviceUtils.isAuto(this)) { + onBackPressed(); + } else { + finish(); } - iconFrame.setVisibility(View.VISIBLE); - } - - itemView.setOnClickListener((v) -> { - Intent intent = new Intent(Intent.ACTION_MANAGE_APP_PERMISSIONS); - intent.putExtra(Intent.EXTRA_PACKAGE_NAME, app.getPackageName()); - intent.putExtra(Intent.EXTRA_USER, UserHandle.getUserHandleForUid(app.getUid())); - startActivity(intent); - mDialog.dismiss(); - }); - - appsList.addView(itemView); - } - - // Set the title of the dialog based on all of the permissions used. - StringBuilder titleBuilder = new StringBuilder(); - int numGroups = usedGroups.size(); - List sortedGroups = new ArrayList<>(usedGroups); - Collator collator = Collator.getInstance( - getResources().getConfiguration().getLocales().get(0)); - sortedGroups.sort(collator); - for (int i = 0; i < numGroups; i++) { - titleBuilder.append(sortedGroups.get(i)); - if (i < numGroups - 2) { - titleBuilder.append(getString(R.string.ongoing_usage_dialog_separator)); - } else if (i < numGroups - 1) { - titleBuilder.append(getString(R.string.ongoing_usage_dialog_last_separator)); - } + return true; + default: + return super.onOptionsItemSelected(item); } - - ((TextView) contentView.requireViewById(R.id.title)).setText( - getString(R.string.ongoing_usage_dialog_title, titleBuilder.toString())); - - return contentView; } - } diff --git a/src/com/android/packageinstaller/permission/ui/handheld/ReviewOngoingUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/ReviewOngoingUsageFragment.java new file mode 100644 index 000000000..10651487e --- /dev/null +++ b/src/com/android/packageinstaller/permission/ui/handheld/ReviewOngoingUsageFragment.java @@ -0,0 +1,230 @@ +/* + * Copyright (C) 2019 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.packageinstaller.permission.ui.handheld; + +import static android.Manifest.permission_group.CAMERA; +import static android.Manifest.permission_group.LOCATION; +import static android.Manifest.permission_group.MICROPHONE; + +import android.app.AlertDialog; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.os.UserHandle; +import android.provider.Settings; +import android.util.ArraySet; +import android.util.Pair; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.preference.PreferenceFragmentCompat; + +import com.android.packageinstaller.permission.model.AppPermissionUsage; +import com.android.packageinstaller.permission.model.AppPermissionUsage.GroupUsage; +import com.android.packageinstaller.permission.model.PermissionApps; +import com.android.packageinstaller.permission.model.PermissionApps.PermissionApp; +import com.android.packageinstaller.permission.model.PermissionUsages; +import com.android.packageinstaller.permission.utils.Utils; +import com.android.permissioncontroller.R; + +import java.text.Collator; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * A dialog listing the currently uses of camera, microphone, and location. + */ +public final class ReviewOngoingUsageFragment extends PreferenceFragmentCompat { + + private @NonNull PermissionUsages mPermissionUsages; + private @Nullable AlertDialog mDialog; + private long mStartTime; + + /** + * @return A new {@link ReviewOngoingUsageFragment} + */ + public static ReviewOngoingUsageFragment newInstance(long numMillis) { + ReviewOngoingUsageFragment fragment = new ReviewOngoingUsageFragment(); + Bundle arguments = new Bundle(); + arguments.putLong(Intent.EXTRA_DURATION_MILLIS, numMillis); + fragment.setArguments(arguments); + return fragment; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + if (!Utils.isPermissionsHubEnabled()) { + return; + } + + long numMillis = getArguments().getLong(Intent.EXTRA_DURATION_MILLIS); + + mPermissionUsages = new PermissionUsages(getActivity()); + mStartTime = Math.max(System.currentTimeMillis() - numMillis, Instant.EPOCH.toEpochMilli()); + mPermissionUsages.load(null, new String[] { CAMERA, LOCATION, MICROPHONE }, mStartTime, + Long.MAX_VALUE, PermissionUsages.USAGE_FLAG_LAST, getActivity().getLoaderManager(), + false, false, this::onPermissionUsagesLoaded, false); + } + + private void onPermissionUsagesLoaded() { + if (getActivity() == null) { + return; + } + + List appPermissionUsages = mPermissionUsages.getUsages(); + + List>> usages = new ArrayList<>(); + ArrayList permApps = new ArrayList<>(); + int numApps = appPermissionUsages.size(); + for (int appNum = 0; appNum < numApps; appNum++) { + AppPermissionUsage appUsage = appPermissionUsages.get(appNum); + + List usedGroups = new ArrayList<>(); + List appGroups = appUsage.getGroupUsages(); + int numGroups = appGroups.size(); + for (int groupNum = 0; groupNum < numGroups; groupNum++) { + GroupUsage groupUsage = appGroups.get(groupNum); + String groupName = groupUsage.getGroup().getName(); + + if (groupUsage.getLastAccessTime() < mStartTime && !groupUsage.isRunning()) { + continue; + } + if (!Utils.isGroupOrBgGroupUserSensitive(groupUsage.getGroup())) { + continue; + } + + usedGroups.add(appGroups.get(groupNum)); + } + + if (!usedGroups.isEmpty()) { + usages.add(Pair.create(appUsage, usedGroups)); + permApps.add(appUsage.getApp()); + } + } + + if (usages.isEmpty()) { + getActivity().finish(); + return; + } + + new PermissionApps.AppDataLoader(getActivity(), () -> showDialog(usages)) + .execute(permApps.toArray(new PermissionApps.PermissionApp[permApps.size()])); + } + + private void showDialog(@NonNull List>> usages) { + mDialog = new AlertDialog.Builder(getActivity()) + .setView(createDialogView(usages)) + .setPositiveButton(R.string.ongoing_usage_dialog_ok, null) + .setNeutralButton(R.string.ongoing_usage_dialog_open_settings, (dialog, which) -> + startActivity(new Intent(Settings.ACTION_PRIVACY_SETTINGS).putExtra( + Intent.EXTRA_DURATION_MILLIS, TimeUnit.MINUTES.toMillis(1)))) + .setOnDismissListener((dialog) -> getActivity().finish()) + .create(); + mDialog.show(); + } + + private @NonNull View createDialogView( + @NonNull List>> usages) { + Context context = getActivity(); + LayoutInflater inflater = LayoutInflater.from(context); + View contentView = inflater.inflate(R.layout.ongoing_usage_dialog_content, null); + ViewGroup appsList = contentView.requireViewById(R.id.items_container); + + // Compute all of the permission group labels that were used. + ArraySet usedGroups = new ArraySet<>(); + int numUsages = usages.size(); + for (int usageNum = 0; usageNum < numUsages; usageNum++) { + List groups = usages.get(usageNum).second; + int numGroups = groups.size(); + for (int groupNum = 0; groupNum < numGroups; groupNum++) { + usedGroups.add(groups.get(groupNum).getGroup().getLabel().toString().toLowerCase()); + } + } + + // Add the layout for each app. + for (int usageNum = 0; usageNum < numUsages; usageNum++) { + Pair> usage = usages.get(usageNum); + PermissionApp app = usage.first.getApp(); + List groups = usage.second; + + View itemView = inflater.inflate(R.layout.ongoing_usage_dialog_item, appsList, false); + + ((TextView) itemView.requireViewById(R.id.app_name)).setText(app.getLabel()); + ((ImageView) itemView.requireViewById(R.id.app_icon)).setImageDrawable(app.getIcon()); + + // Add the icons for the groups this app used as long as multiple groups were used by + // some app. + if (usedGroups.size() > 1) { + ViewGroup iconFrame = itemView.requireViewById(R.id.icons); + int numGroups = usages.get(usageNum).second.size(); + for (int groupNum = 0; groupNum < numGroups; groupNum++) { + ViewGroup group = (ViewGroup) inflater.inflate(R.layout.image_view, null); + ((ImageView) group.requireViewById(R.id.icon)).setImageDrawable( + Utils.applyTint(context, groups.get(groupNum).getGroup().getIconResId(), + android.R.attr.colorControlNormal)); + iconFrame.addView(group); + } + iconFrame.setVisibility(View.VISIBLE); + } + + itemView.setOnClickListener((v) -> { + Intent intent = new Intent(Intent.ACTION_MANAGE_APP_PERMISSIONS); + intent.putExtra(Intent.EXTRA_PACKAGE_NAME, app.getPackageName()); + intent.putExtra(Intent.EXTRA_USER, UserHandle.getUserHandleForUid(app.getUid())); + startActivity(intent); + mDialog.dismiss(); + }); + + appsList.addView(itemView); + } + + // Set the title of the dialog based on all of the permissions used. + StringBuilder titleBuilder = new StringBuilder(); + int numGroups = usedGroups.size(); + List sortedGroups = new ArrayList<>(usedGroups); + Collator collator = Collator.getInstance( + getResources().getConfiguration().getLocales().get(0)); + sortedGroups.sort(collator); + for (int i = 0; i < numGroups; i++) { + titleBuilder.append(sortedGroups.get(i)); + if (i < numGroups - 2) { + titleBuilder.append(getString(R.string.ongoing_usage_dialog_separator)); + } else if (i < numGroups - 1) { + titleBuilder.append(getString(R.string.ongoing_usage_dialog_last_separator)); + } + } + + ((TextView) contentView.requireViewById(R.id.title)).setText( + getString(R.string.ongoing_usage_dialog_title, titleBuilder.toString())); + + return contentView; + } + + @Override + public void onCreatePreferences(Bundle bundle, String s) { + // empty + } +} -- GitLab From 592f30a3692628a6acd86e7e5bc6470633442fd4 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Mon, 25 Mar 2019 12:43:58 -0700 Subject: [PATCH 486/701] Change PermissionAppFragment's header for Location to "Allowed all the time" Fixes: 128514107 Test: View PermissionAppFragment for multiple permissions. Change-Id: I1149a665f905a77eca8ff7e154a93f6dd087c538 --- res/values/strings.xml | 3 +++ .../permission/ui/handheld/PermissionAppsFragment.java | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/res/values/strings.xml b/res/values/strings.xml index 1d6ed9d35..229ab4868 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -472,6 +472,9 @@ Allowed + + Allowed all the time + Allowed only while in use diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java index 5d9a6b0ee..a107090cc 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java @@ -233,6 +233,7 @@ public final class PermissionAppsFragment extends SettingsWithLargeHeader implem mHasSystemApps = false; boolean menuOptionsInvalided = false; + boolean hasPermissionWithBackgroundMode = false; ArrayList sortedApps = new ArrayList<>(permissionApps.getApps()); sortedApps.sort((x, y) -> mCollator.compare(x.getLabel(), y.getLabel())); @@ -241,6 +242,9 @@ public final class PermissionAppsFragment extends SettingsWithLargeHeader implem PermissionApp app = sortedApps.get(i); AppPermissionGroup group = app.getPermissionGroup(); + hasPermissionWithBackgroundMode = + hasPermissionWithBackgroundMode || group.hasPermissionWithBackgroundMode(); + if (!Utils.shouldShowPermission(getContext(), group)) { continue; } @@ -342,6 +346,10 @@ public final class PermissionAppsFragment extends SettingsWithLargeHeader implem grantedCount, mExtraScreen.getPreferenceCount())); } + if (hasPermissionWithBackgroundMode) { + allowed.setTitle(R.string.allowed_always_header); + } + if (allowed.getPreferenceCount() == 0) { Preference empty = new Preference(context); empty.setTitle(getString(R.string.no_apps_allowed)); -- GitLab From 8b387602f64f159d6212314bc08cf639b424d8aa Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Wed, 20 Mar 2019 18:38:45 -0700 Subject: [PATCH 487/701] Remove filter spinners. Test: View Permissions Hub, change permission/time filter. Change-Id: I833ac9bb7b2fc5593efcaee98aa45a59a7229138 --- PermissionController.mk | 1 - .../permission_usage_filter_spinners.xml | 54 ---- .../permission/ui/handheld/FilterSpinner.java | 165 ------------- .../ui/handheld/PermissionUsageFragment.java | 231 +++++++----------- 4 files changed, 87 insertions(+), 364 deletions(-) delete mode 100644 res/layout/permission_usage_filter_spinners.xml delete mode 100644 src/com/android/packageinstaller/permission/ui/handheld/FilterSpinner.java diff --git a/PermissionController.mk b/PermissionController.mk index 6b5ff81e8..4d5b4e78c 100644 --- a/PermissionController.mk +++ b/PermissionController.mk @@ -30,7 +30,6 @@ LOCAL_STATIC_ANDROID_LIBRARIES += \ SettingsLibRestrictedLockUtils \ SettingsLibAppPreference \ SettingsLibSearchWidget \ - SettingsLibSettingsSpinner \ SettingsLibLayoutPreference \ SettingsLibActionBarShadow \ SettingsLibProgressBar diff --git a/res/layout/permission_usage_filter_spinners.xml b/res/layout/permission_usage_filter_spinners.xml deleted file mode 100644 index 201e163d6..000000000 --- a/res/layout/permission_usage_filter_spinners.xml +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/src/com/android/packageinstaller/permission/ui/handheld/FilterSpinner.java b/src/com/android/packageinstaller/permission/ui/handheld/FilterSpinner.java deleted file mode 100644 index 0380e7d4f..000000000 --- a/src/com/android/packageinstaller/permission/ui/handheld/FilterSpinner.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.packageinstaller.permission.ui.handheld; - -import static java.util.concurrent.TimeUnit.DAYS; -import static java.util.concurrent.TimeUnit.HOURS; -import static java.util.concurrent.TimeUnit.MINUTES; - -import android.content.Context; - -import androidx.annotation.NonNull; -import androidx.annotation.StringRes; - -import com.android.permissioncontroller.R; -import com.android.settingslib.widget.settingsspinner.SettingsSpinnerAdapter; - -import java.util.ArrayList; - -/** - * Utility class for using filter spinners. - */ -public class FilterSpinner { - - private FilterSpinner() { - /* do nothing - hide constructor */ - } - - /** - * An adapter that stores the entries in a filter spinner. - * - * @param The type of the entries in the filter spinner. - */ - public static class FilterSpinnerAdapter extends - SettingsSpinnerAdapter { - private final ArrayList mFilterOptions = new ArrayList<>(); - - FilterSpinnerAdapter(@NonNull Context context) { - super(context); - } - - /** - * Add the given filter to this adapter. - * - * @param filter the filter to add - */ - public void addFilter(@NonNull T filter) { - mFilterOptions.add(filter); - notifyDataSetChanged(); - } - - /** - * Get the filter at the given position. - * - * @param position the index of the filter to get. - * - * @return the filter at the given index. - */ - public T getFilter(int position) { - return mFilterOptions.get(position); - } - - @Override - public int getCount() { - return mFilterOptions.size(); - } - - @Override - public CharSequence getItem(int position) { - return mFilterOptions.get(position).getLabel(); - } - - @Override - public void clear() { - mFilterOptions.clear(); - super.clear(); - } - - } - - /** - * An interface to represent items that we can use as filters. - */ - public interface SpinnerItem { - /** - * Get the label of this item to display to the user. - * - * @return the label of this item. - */ - @NonNull String getLabel(); - } - - /** - * A spinner item representing a given time, e.g., "in the last hour". - */ - public static class TimeFilterItem implements SpinnerItem { - private final long mTime; - private final @NonNull String mLabel; - private final @StringRes int mListTitleRes; - - TimeFilterItem(long time, @NonNull String label, @StringRes int listTitleRes) { - mTime = time; - mLabel = label; - mListTitleRes = listTitleRes; - } - - /** - * Get the time represented by this object in milliseconds. - * - * @return the time represented by this object. - */ - public long getTime() { - return mTime; - } - - public @NonNull String getLabel() { - return mLabel; - } - - public @StringRes int getListTitleRes() { - return mListTitleRes; - } - } - - /** - * Add time filter entries. - * - * @param adapter the filter spinner adapter - * @param context the context - */ - public static void addTimeFilters(@NonNull FilterSpinnerAdapter adapter, - @NonNull Context context) { - adapter.addFilter(new TimeFilterItem(Long.MAX_VALUE, - context.getString(R.string.permission_usage_any_time), - R.string.permission_usage_list_title_any_time)); - adapter.addFilter(new TimeFilterItem(DAYS.toMillis(7), - context.getString(R.string.permission_usage_last_7_days), - R.string.permission_usage_list_title_last_7_days)); - adapter.addFilter(new TimeFilterItem(DAYS.toMillis(1), - context.getString(R.string.permission_usage_last_day), - R.string.permission_usage_list_title_last_day)); - adapter.addFilter(new TimeFilterItem(HOURS.toMillis(1), - context.getString(R.string.permission_usage_last_hour), - R.string.permission_usage_list_title_last_hour)); - adapter.addFilter(new TimeFilterItem(MINUTES.toMillis(15), - context.getString(R.string.permission_usage_last_15_minutes), - R.string.permission_usage_list_title_last_15_minutes)); - adapter.addFilter(new TimeFilterItem(MINUTES.toMillis(1), - context.getString(R.string.permission_usage_last_minute), - R.string.permission_usage_list_title_last_minute)); - } -} diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java index 97f2d664d..d5922be63 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java @@ -17,6 +17,9 @@ package com.android.packageinstaller.permission.ui.handheld; import static java.lang.annotation.RetentionPolicy.SOURCE; +import static java.util.concurrent.TimeUnit.DAYS; +import static java.util.concurrent.TimeUnit.HOURS; +import static java.util.concurrent.TimeUnit.MINUTES; import android.app.ActionBar; import android.app.AlertDialog; @@ -34,16 +37,14 @@ import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemSelectedListener; import android.widget.ImageView; import android.widget.RadioButton; -import android.widget.Spinner; import android.widget.TextView; import androidx.annotation.IntDef; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.annotation.StringRes; import androidx.fragment.app.DialogFragment; import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceScreen; @@ -54,9 +55,6 @@ import com.android.packageinstaller.permission.model.AppPermissionUsage.GroupUsa import com.android.packageinstaller.permission.model.PermissionApps; import com.android.packageinstaller.permission.model.PermissionApps.PermissionApp; import com.android.packageinstaller.permission.model.PermissionUsages; -import com.android.packageinstaller.permission.ui.handheld.FilterSpinner.FilterSpinnerAdapter; -import com.android.packageinstaller.permission.ui.handheld.FilterSpinner.SpinnerItem; -import com.android.packageinstaller.permission.ui.handheld.FilterSpinner.TimeFilterItem; import com.android.packageinstaller.permission.utils.Utils; import com.android.permissioncontroller.R; import com.android.settingslib.HelpUtils; @@ -76,7 +74,7 @@ import java.util.Set; * AppPermissionsFragment. */ public class PermissionUsageFragment extends SettingsWithLargeHeader implements - PermissionUsages.PermissionsUsagesChangeCallback, OnItemSelectedListener { + PermissionUsages.PermissionsUsagesChangeCallback { private static final String LOG_TAG = "PermissionUsageFragment"; @Retention(SOURCE) @@ -97,12 +95,12 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements private static final String KEY_PERMS_INDEX = "_perms_index"; private static final String PERMS_INDEX_KEY = PermissionUsageFragment.class.getName() + KEY_PERMS_INDEX; - private static final String KEY_SPINNER_TIME_INDEX = "_time_index"; - private static final String SPINNER_TIME_INDEX_KEY = PermissionUsageFragment.class.getName() - + KEY_SPINNER_TIME_INDEX; - private static final String KEY_SPINNER_SORT_INDEX = "_sort_index"; - private static final String SPINNER_SORT_INDEX_KEY = PermissionUsageFragment.class.getName() - + KEY_SPINNER_SORT_INDEX; + private static final String KEY_TIME_INDEX = "_time_index"; + private static final String TIME_INDEX_KEY = PermissionUsageFragment.class.getName() + + KEY_TIME_INDEX; + private static final String KEY_SORT = "_sort"; + private static final String SORT_KEY = PermissionUsageFragment.class.getName() + + KEY_SORT; private static final String KEY_FINISHED_INITIAL_LOAD = "_finished_initial_load"; private static final String FINISHED_INITIAL_LOAD_KEY = PermissionUsageFragment.class.getName() + KEY_FINISHED_INITIAL_LOAD; @@ -111,7 +109,10 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements private Collator mCollator; + private @NonNull List mFilterTimes; + private int mFilterTimeIndex; private String mFilterGroup; + private @SortOption int mSort; private boolean mShowSystem; private boolean mHasSystemApps; @@ -120,11 +121,6 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements private MenuItem mSortByApp; private MenuItem mSortByTime; - private Spinner mFilterSpinnerTime; - private FilterSpinnerAdapter mFilterAdapterTime; - private Spinner mSortSpinner; - private FilterSpinnerAdapter mSortAdapter; - private ArrayMap mGroupAppCounts; private boolean mFinishedInitialLoad; @@ -135,18 +131,6 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements */ private String mSavedGroupName; - /** - * Only used to restore time spinner state after onCreate. Once the list of times is reported, - * this becomes invalid. - */ - private int mSavedTimeSpinnerIndex; - - /** - * Only used to restore sort spinner state after onCreate. Once the list of sorts is reported, - * this becomes invalid. - */ - private int mSavedSortSpinnerIndex; - /** * @return A new fragment */ @@ -162,26 +146,17 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements return fragment; } - @Override - public void onStart() { - super.onStart(); - getActivity().setTitle(R.string.permission_usage_title); - - if (mFinishedInitialLoad) { - setProgressBarVisible(true); - } - } - @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - mSavedSortSpinnerIndex = 1; + mSort = SORT_RECENT_APPS; + initializeTimeFilter(); if (savedInstanceState != null) { mShowSystem = savedInstanceState.getBoolean(SHOW_SYSTEM_KEY); mSavedGroupName = savedInstanceState.getString(PERMS_INDEX_KEY); - mSavedTimeSpinnerIndex = savedInstanceState.getInt(SPINNER_TIME_INDEX_KEY); - mSavedSortSpinnerIndex = savedInstanceState.getInt(SPINNER_SORT_INDEX_KEY); + mFilterTimeIndex = savedInstanceState.getInt(TIME_INDEX_KEY); + mSort = savedInstanceState.getInt(SORT_KEY); mFinishedInitialLoad = savedInstanceState.getBoolean(FINISHED_INITIAL_LOAD_KEY); } @@ -204,86 +179,66 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements } @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - Context context = getPreferenceManager().getContext(); - ViewGroup root = (ViewGroup) super.onCreateView(inflater, container, savedInstanceState); - - // Setup filter spinners. - View header = inflater.inflate(R.layout.permission_usage_filter_spinners, root, false); - getPreferencesContainer().addView(header, 1); - - mFilterSpinnerTime = header.requireViewById(R.id.filter_spinner_time); - mFilterAdapterTime = new FilterSpinnerAdapter<>(context); - mFilterSpinnerTime.setAdapter(mFilterAdapterTime); - mFilterSpinnerTime.setOnItemSelectedListener(this); - - mSortSpinner = header.requireViewById(R.id.sort_spinner); - mSortAdapter = new FilterSpinnerAdapter<>(context); - mSortSpinner.setAdapter(mSortAdapter); - mSortSpinner.setOnItemSelectedListener(this); - - // Add time spinner entries. - FilterSpinner.addTimeFilters(mFilterAdapterTime, context); - mFilterSpinnerTime.setSelection(mSavedTimeSpinnerIndex); - initializeTimeFilter(); + public void onStart() { + super.onStart(); + getActivity().setTitle(R.string.permission_usage_title); - // Add sort spinner entries. - mSortAdapter.addFilter(new SortItem(context.getString(R.string.sort_spinner_recent), - SORT_RECENT)); - mSortAdapter.addFilter( - new SortItem(context.getString(R.string.sort_spinner_most_permissions), - SORT_RECENT_APPS)); - mSortSpinner.setSelection(mSavedSortSpinnerIndex); + if (mFinishedInitialLoad) { + setProgressBarVisible(true); + } - // STOPSHIP: Re-enable spinners afetr user study completes. - header.requireViewById(R.id.filter_spinner_bar).setVisibility(View.GONE); reloadData(); - - return root; } /** - * Initialize the time filter spinner to show the smallest entry greater than the time passed - * in as an argument. If nothing is passed, this does nothing. + * Initialize the time filter to show the smallest entry greater than the time passed in as an + * argument. If nothing is passed, this simply initializes the possible values. */ private void initializeTimeFilter() { + Context context = getPreferenceManager().getContext(); + mFilterTimes = new ArrayList<>(); + mFilterTimes.add(new TimeFilterItem(Long.MAX_VALUE, + context.getString(R.string.permission_usage_any_time), + R.string.permission_usage_list_title_any_time)); + mFilterTimes.add(new TimeFilterItem(DAYS.toMillis(7), + context.getString(R.string.permission_usage_last_7_days), + R.string.permission_usage_list_title_last_7_days)); + mFilterTimes.add(new TimeFilterItem(DAYS.toMillis(1), + context.getString(R.string.permission_usage_last_day), + R.string.permission_usage_list_title_last_day)); + mFilterTimes.add(new TimeFilterItem(HOURS.toMillis(1), + context.getString(R.string.permission_usage_last_hour), + R.string.permission_usage_list_title_last_hour)); + mFilterTimes.add(new TimeFilterItem(MINUTES.toMillis(15), + context.getString(R.string.permission_usage_last_15_minutes), + R.string.permission_usage_list_title_last_15_minutes)); + mFilterTimes.add(new TimeFilterItem(MINUTES.toMillis(1), + context.getString(R.string.permission_usage_last_minute), + R.string.permission_usage_list_title_last_minute)); + long numMillis = getArguments().getLong(Intent.EXTRA_DURATION_MILLIS); long supremum = Long.MAX_VALUE; int supremumIndex = -1; - for (int i = 0; i < mFilterAdapterTime.getCount(); i++) { - long curTime = mFilterAdapterTime.getFilter(i).getTime(); + int numTimes = mFilterTimes.size(); + for (int i = 0; i < numTimes; i++) { + long curTime = mFilterTimes.get(i).getTime(); if (curTime >= numMillis && curTime <= supremum) { supremum = curTime; supremumIndex = i; } } if (supremumIndex != -1) { - mFilterSpinnerTime.setSelection(supremumIndex); - } - } - - @Override - public void onItemSelected(AdapterView parent, View view, int position, long id) { - if (parent == mFilterSpinnerTime) { - reloadData(); - } else if (parent == mSortSpinner) { - // We already loaded all data, so don't reload - updateUI(); + mFilterTimeIndex = supremumIndex; } } - @Override - public void onNothingSelected(AdapterView parent) { - } - @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putBoolean(SHOW_SYSTEM_KEY, mShowSystem); outState.putString(PERMS_INDEX_KEY, mFilterGroup); - outState.putInt(SPINNER_TIME_INDEX_KEY, mFilterSpinnerTime.getSelectedItemPosition()); - outState.putInt(SPINNER_SORT_INDEX_KEY, mSortSpinner.getSelectedItemPosition()); + outState.putInt(TIME_INDEX_KEY, mFilterTimeIndex); + outState.putInt(SORT_KEY, mSort); outState.putBoolean(FINISHED_INITIAL_LOAD_KEY, mFinishedInitialLoad); } @@ -316,12 +271,12 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements getActivity().finish(); return true; case MENU_SORT_BY_APP: - mSortSpinner.setSelection(1); + mSort = SORT_RECENT_APPS; updateUI(); updateMenu(); break; case MENU_SORT_BY_TIME: - mSortSpinner.setSelection(0); + mSort = SORT_RECENT; updateUI(); updateMenu(); break; @@ -350,8 +305,8 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements mShowSystemMenu.setVisible(!mShowSystem); mHideSystemMenu.setVisible(mShowSystem); } - mSortByApp.setVisible(mSortSpinner.getSelectedItemPosition() == 0); - mSortByTime.setVisible(mSortSpinner.getSelectedItemPosition() == 1); + mSortByApp.setVisible(mSort != SORT_RECENT_APPS); + mSortByTime.setVisible(mSort != SORT_RECENT); } @Override @@ -397,7 +352,7 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements mHasSystemApps = false; - final TimeFilterItem timeFilterItem = getSelectedFilterItem(); + final TimeFilterItem timeFilterItem = mFilterTimes.get(mFilterTimeIndex); long curTime = System.currentTimeMillis(); long startTime = (timeFilterItem == null ? 0 : (curTime - timeFilterItem.getTime())); @@ -466,13 +421,12 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements } // Sort the apps. - final int sortOption = getSelectedSortOption(); - if (sortOption == SORT_RECENT) { + if (mSort == SORT_RECENT) { usages.sort(PermissionUsageFragment::compareAccessRecency); - } else if (sortOption == SORT_RECENT_APPS) { + } else if (mSort == SORT_RECENT_APPS) { usages.sort(PermissionUsageFragment::compareAccessAppRecency); } else { - Log.w(LOG_TAG, "Unexpected sort option: " + sortOption); + Log.w(LOG_TAG, "Unexpected sort option: " + mSort); } usages.removeIf((Pair usage) -> mFilterGroup != null @@ -497,12 +451,12 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements String accessTimeString = Utils.getAbsoluteLastUsageString(context, groupUsage); - if (lastAppPermissionUsage != appPermissionUsage || (sortOption == SORT_RECENT + if (lastAppPermissionUsage != appPermissionUsage || (mSort == SORT_RECENT && !accessTimeString.equals(lastAccessTimeString))) { setPermissionSummary(parent, groups); // Add a "parent" entry for the app that will expand to the individual entries. parent = createExpandablePreferenceGroup(context, appPermissionUsage, - sortOption == SORT_RECENT ? accessTimeString : null); + mSort == SORT_RECENT ? accessTimeString : null); category.addPreference(parent); lastAppPermissionUsage = appPermissionUsage; groups = new ArrayList<>(); @@ -522,24 +476,6 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements }).execute(permApps.toArray(new PermissionApps.PermissionApp[permApps.size()])); } - private TimeFilterItem getSelectedFilterItem() { - // Get the current values of the time filter. - final int pos = mFilterSpinnerTime.getSelectedItemPosition(); - TimeFilterItem timeFilterItem = null; - if (pos != AdapterView.INVALID_POSITION) { - timeFilterItem = mFilterAdapterTime.getFilter(pos); - } - return timeFilterItem; - } - - private int getSelectedSortOption() { - final int pos = mSortSpinner.getSelectedItemPosition(); - if (pos == AdapterView.INVALID_POSITION) { - return SORT_RECENT_APPS; - } - return mSortAdapter.getFilter(pos).getSortOption(); - } - private void addGroupUser(String app) { Integer count = mGroupAppCounts.get(app); if (count == null) { @@ -569,10 +505,7 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements * Reloads the data to show. */ private void reloadData() { - final TimeFilterItem timeFilterItem = getSelectedFilterItem(); - if (timeFilterItem == null) { - return; - } + final TimeFilterItem timeFilterItem = mFilterTimes.get(mFilterTimeIndex); final long filterTimeBeginMillis = Math.max(System.currentTimeMillis() - timeFilterItem.getTime(), Instant.EPOCH.toEpochMilli()); mPermissionUsages.load(null /*filterPackageName*/, null /*filterPermissionGroups*/, @@ -798,7 +731,7 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements groups.sort( (x, y) -> mCollator.compare(x.getLabel().toString(), y.getLabel().toString())); - // Create the spinner entries. + // Create the dialog entries. String[] groupNames = new String[groups.size() + 1]; CharSequence[] groupLabels = new CharSequence[groupNames.length]; int[] groupIcons = new int[groupNames.length]; @@ -925,18 +858,17 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements private void showTimeFilterDialog() { Context context = getPreferenceManager().getContext(); - CharSequence[] labels = new CharSequence[mFilterAdapterTime.getCount()]; + CharSequence[] labels = new CharSequence[mFilterTimes.size()]; for (int i = 0; i < labels.length; i++) { - labels[i] = mFilterAdapterTime.getFilter(i).getLabel(); + labels[i] = mFilterTimes.get(i).getLabel(); } - int selection = mFilterSpinnerTime.getSelectedItemPosition(); // Create the dialog Bundle args = new Bundle(); args.putCharSequence(TimeFilterDialog.TITLE, context.getString(R.string.filter_by_title)); args.putCharSequenceArray(TimeFilterDialog.ELEMS, labels); - args.putInt(TimeFilterDialog.SELECTION, selection); + args.putInt(TimeFilterDialog.SELECTION, mFilterTimeIndex); TimeFilterDialog chooserDialog = new TimeFilterDialog(); chooserDialog.setArguments(args); chooserDialog.setTargetFragment(this, 0); @@ -950,7 +882,7 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements * @param selectedIndex The index of the dialog option selected by the user. */ private void onTimeSelected(int selectedIndex) { - mFilterSpinnerTime.setSelection(selectedIndex); + mFilterTimeIndex = selectedIndex; reloadData(); } @@ -982,23 +914,34 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements } /** - * A spinner item representing different ways to sort the entries. + * A class representing a given time, e.g., "in the last hour". */ - private static class SortItem implements SpinnerItem { + private static class TimeFilterItem { + private final long mTime; private final @NonNull String mLabel; - private final @SortOption int mSortOption; + private final @StringRes int mListTitleRes; - SortItem(@NonNull String label, @SortOption int sortOption) { + TimeFilterItem(long time, @NonNull String label, @StringRes int listTitleRes) { + mTime = time; mLabel = label; - mSortOption = sortOption; + mListTitleRes = listTitleRes; + } + + /** + * Get the time represented by this object in milliseconds. + * + * @return the time represented by this object. + */ + public long getTime() { + return mTime; } public @NonNull String getLabel() { return mLabel; } - public @SortOption int getSortOption() { - return mSortOption; + public @StringRes int getListTitleRes() { + return mListTitleRes; } } } -- GitLab From 25b5b4275e71a4e80e821b47faaa640c98cc673d Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Tue, 19 Mar 2019 15:51:34 -0700 Subject: [PATCH 488/701] Add strings necessary for the new UI design. Bug: 128713569 Test: build Change-Id: I78dd16e65eae448333b04f24cf28721145df3f37 --- res/values/strings.xml | 164 ++++++++++++++++++++++++++++++++++------- res/xml/roles.xml | 24 +++--- 2 files changed, 148 insertions(+), 40 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 35eb65f75..e34027089 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -544,12 +544,147 @@ These apps can view your screen, actions, and inputs, perform actions, and control the display. + + Default assist app + + Assist app + + Assist apps can help you based on information from the screen you\u2019re viewing. Some apps support both launcher and voice input services to give you integrated assistance. + + Gets access to SMS, call log + + Set %1$s as your default assist app? + + + Default browser app + + Browser app + + Apps that give you access to the internet and display links that you tap + + No permissions needed + + Set %1$s as your default browser app? + + + Default phone app + + Phone app + + Apps that allow you to make and receive telephone calls on your device + + Gets access to call log, send SMS + + Set %1$s as your default phone app? + + + Default SMS app + + SMS app + + Apps that allow you to use your phone number to send and receive short text messages, photos, videos, and more + + Gets access to contacts, SMS, phone + + Set %1$s as your default SMS app? + + + Default emergency app + + Emergency app + + Apps that allow you to record your medical info and make it accessible to emergency responders; to get alerts about severe weather events and disasters; to notify others when you need help + + No permissions needed + + Set %1$s as your default emergency app? + + + Default home app + + Home app + + Apps, often called launchers, that replace the Home screens on your Android device and give you access to the contents and features of your device + + No permissions needed + + Set %1$s as your default home app? + + + Default music app + + Music app + + Apps that allow you to play songs, podcasts, and other audio + + Gets access to audio + + Set %1$s as your default music app? + + + Default gallery app + + Gallery app + + Apps that allow you to view, organize, protect, and share your photos and videos + + Gets access to photos and videos + + Set %1$s as your default gallery app? + + + Default car mode phone app + + Car mode phone app + + + + + + Set %1$s as your default car mode phone app? + + + Default call redirecting app + + Call redirecting app + + Apps that allow you to forward calls to another phone number + + No permissions needed + + Set %1$s as your default call redirection app? + + + Default caller ID & spam app + + Caller ID & spam app + + Apps that allow you to identify incoming calls, block spam and robocalls, blacklist unwanted numbers, and so on + + No permissions needed + + Set %1$s as your default caller ID & spam app? + + + Default call companion app + + Call companion app + + + + + + Set %1$s as your default call companion app? + Set %1$s as your default %2$s? Current default + + Don\u2019t ask again + Set as default @@ -609,40 +744,13 @@ No apps - - - - Assist app - - Browser app - - Phone app - - SMS app - - Emergency app - - Home app - - Music app - - Gallery app - - Car mode phone app - - Call redirecting app - - Caller ID and spam app - - Call companion app - Doesn\u2019t support work profile Note: If you restart your device and have a screen lock set, this app can\u2019t start until you unlock your device. - + The assistant will be able to read information about apps in use on your system, including information visible on your screen or accessible within the apps. @@ -349,7 +349,7 @@ name="android.app.role.MUSIC" behavior="MusicRoleBehavior" exclusive="true" - label="@string/role_label_music"> + label="@string/role_music_short_label"> @@ -384,7 +384,7 @@ name="android.app.role.GALLERY" behavior="GalleryRoleBehavior" exclusive="true" - label="@string/role_label_gallery"> + label="@string/role_gallery_short_label"> @@ -420,7 +420,7 @@ + label="@string/role_car_mode_dialer_short_label"> + label="@string/role_call_redirection_short_label"> @@ -453,7 +453,7 @@ + label="@string/role_call_screening_short_label"> @@ -467,7 +467,7 @@ + label="@string/role_call_companion_short_label"> Date: Mon, 25 Mar 2019 14:30:03 -0700 Subject: [PATCH 489/701] Remove icons from the permission filter dialog. Bug: 129289903 Test: View and click various permissions in the dialog. Change-Id: Id18eeef0a299ea378fa8f8135824496eaf07b296 --- res/layout/permission_filter_dialog_item.xml | 9 --------- res/values/overlayable.xml | 2 -- res/values/styles.xml | 13 ------------- .../ui/handheld/PermissionUsageFragment.java | 12 ------------ 4 files changed, 36 deletions(-) diff --git a/res/layout/permission_filter_dialog_item.xml b/res/layout/permission_filter_dialog_item.xml index 5acbb7938..e13c6c68c 100644 --- a/res/layout/permission_filter_dialog_item.xml +++ b/res/layout/permission_filter_dialog_item.xml @@ -23,15 +23,6 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" /> - - - - - - diff --git a/res/values/overlayable.xml b/res/values/overlayable.xml index 2172f58bc..ccf05c77c 100644 --- a/res/values/overlayable.xml +++ b/res/values/overlayable.xml @@ -85,8 +85,6 @@ - - diff --git a/res/values/styles.xml b/res/values/styles.xml index 406bbe882..bfd62eb07 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -345,19 +345,6 @@ center_vertical - - - - @@ -324,6 +324,7 @@ match_parent wrap_content vertical + 8dp - + + + + \ No newline at end of file diff --git a/res/values/themes.xml b/res/values/themes.xml index d479ed306..ca24edc10 100644 --- a/res/values/themes.xml +++ b/res/values/themes.xml @@ -64,4 +64,8 @@ parent="@android:style/Theme.DeviceDefault.Light.Dialog"> + + -- GitLab From 6165e8f56b4cbdddd38746a663a6ac3fa640fe1d Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Wed, 27 Mar 2019 13:30:15 -0700 Subject: [PATCH 503/701] After filtering Permissions Hub by permission, make the back button return to the unfiltered view. Previously, filtering by a permission group simply changed the filter in the current fragment. Thus pressing the back button returned to the previous screen instead of undoing the filter. This changes that behavior. Also update the string for removing the filter. Fixes: 129415632 Test: Open Permissions Hub, filter by group, press back, see Permissions Hub. Test: Open filtered view, press "See all", press back, see filtered view. Test: Launch filtered view initially, press back, return to parent. Change-Id: Id77b24bb30986ddbe8826297cd2d6187f1786a41 --- res/values/strings.xml | 2 +- .../ui/handheld/PermissionUsageFragment.java | 22 +++++++++---------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index ddb318aaa..70a3f2834 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -344,7 +344,7 @@ Filtered by: %1$s - Remove filter + See all in Dashboard Filter by diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java index bcf148e7b..91bc54657 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java @@ -50,6 +50,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.StringRes; import androidx.fragment.app.DialogFragment; +import androidx.fragment.app.Fragment; import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceScreen; @@ -200,6 +201,8 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements setProgressBarVisible(true); } + hideHeader(); + reloadData(); } @@ -417,7 +420,6 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements // Update header. if (mFilterGroup == null) { screen.addPreference(createBarChart(usages, timeFilterItem, context)); - hideHeader(); } else { AppPermissionGroup group = getGroup(mFilterGroup); if (group != null) { @@ -426,9 +428,7 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements context.getString(R.string.app_permission_usage_filter_label, group.getLabel()), null); setSummary(context.getString(R.string.app_permission_usage_remove_filter), v -> { - mFilterGroup = null; - // We already loaded all data, so don't reload - updateUI(); + onPermissionGroupSelected(null); }); } } @@ -602,11 +602,7 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements BarViewInfo barViewInfo = new BarViewInfo(icon, count, group.getLabel(), context.getResources().getQuantityString(R.plurals.permission_usage_bar_label, count, count), group.getLabel()); - barViewInfo.setClickListener(v -> { - mFilterGroup = group.getName(); - // We already loaded all data, so don't reload - updateUI(); - }); + barViewInfo.setClickListener(v -> onPermissionGroupSelected(group.getName())); builder.addBarViewInfo(barViewInfo); } @@ -873,9 +869,11 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements * all entries. */ private void onPermissionGroupSelected(@Nullable String selectedGroup) { - mFilterGroup = selectedGroup; - // We already loaded all data, so don't reload - updateUI(); + Fragment frag = newInstance(selectedGroup, mFilterTimes.get(mFilterTimeIndex).getTime()); + getFragmentManager().beginTransaction() + .replace(android.R.id.content, frag) + .addToBackStack("PermissionUsage") + .commit(); } /** -- GitLab From 835c6dd94677ca44f0f2876c812177d137944229 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Wed, 27 Mar 2019 13:03:10 -0700 Subject: [PATCH 504/701] Tweak Permissions Hub style. Make the gear icon gray instead of blue. Reduce the space between the permission icon and its label. Make the permission icon smaller when it's in the header of Permissions Hub and PermissionAppsFragment. Bug: 128439459 Test: View screen. Change-Id: Ie6596175d7351aaf4d2042eb5e81d06df7412686 --- res/drawable/ic_settings_accent.xml | 29 +++++++++++++++++++ res/layout/preference_usage.xml | 2 +- res/values/dimens.xml | 1 + .../ui/handheld/AppPermissionFragment.java | 2 +- .../ui/handheld/AppPermissionsFragment.java | 4 +-- .../ui/handheld/PermissionAppsFragment.java | 4 +-- .../ui/handheld/PermissionUsageFragment.java | 4 +-- .../ui/handheld/SettingsWithLargeHeader.java | 11 ++++++- 8 files changed, 48 insertions(+), 9 deletions(-) create mode 100644 res/drawable/ic_settings_accent.xml diff --git a/res/drawable/ic_settings_accent.xml b/res/drawable/ic_settings_accent.xml new file mode 100644 index 000000000..fd826b342 --- /dev/null +++ b/res/drawable/ic_settings_accent.xml @@ -0,0 +1,29 @@ + + + + + + \ No newline at end of file diff --git a/res/layout/preference_usage.xml b/res/layout/preference_usage.xml index 6ff031786..f606aa79d 100644 --- a/res/layout/preference_usage.xml +++ b/res/layout/preference_usage.xml @@ -45,7 +45,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="start|center_vertical" - android:paddingEnd="16dp" + android:paddingEnd="8dp" android:orientation="horizontal" app:layout_constraintStart_toEndOf="@+id/image_frame_include" app:layout_constraintBottom_toBottomOf="@android:id/title"/> diff --git a/res/values/dimens.xml b/res/values/dimens.xml index f881242a6..f80c8614e 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -24,6 +24,7 @@ 16dp 24dp + 32dp 384dp diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java index e84375152..01fd61787 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java @@ -178,7 +178,7 @@ public class AppPermissionFragment extends SettingsWithLargeHeader { } String appLabel = Utils.getFullAppLabel(mGroup.getApp().applicationInfo, context); - setHeader(getAppIcon(), appLabel, null); + setHeader(getAppIcon(), appLabel, null, false); updateHeader(root.requireViewById(R.id.large_header)); ((TextView) root.requireViewById(R.id.permission_message)).setText( diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java index c1505aef3..aac179162 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java @@ -177,7 +177,7 @@ public final class AppPermissionsFragment extends SettingsWithLargeHeader { } Drawable icon = Utils.getBadgedIcon(activity, appInfo); - fragment.setHeader(icon, Utils.getFullAppLabel(appInfo, activity), infoIntent); + fragment.setHeader(icon, Utils.getFullAppLabel(appInfo, activity), infoIntent, false); ActionBar ab = activity.getActionBar(); if (ab != null) { @@ -329,7 +329,7 @@ public final class AppPermissionsFragment extends SettingsWithLargeHeader { public void onCreate(Bundle savedInstanceState) { mOuterFragment = (AppPermissionsFragment) getTargetFragment(); super.onCreate(savedInstanceState); - setHeader(mOuterFragment.mIcon, mOuterFragment.mLabel, null); + setHeader(mOuterFragment.mIcon, mOuterFragment.mLabel, null, false); setHasOptionsMenu(true); setPreferenceScreen(mOuterFragment.mExtraScreen); } diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java index c480a9f07..f2d54f319 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java @@ -172,7 +172,7 @@ public final class PermissionAppsFragment extends SettingsWithLargeHeader implem final Drawable icon = permissionApps.getIcon(); final CharSequence label = permissionApps.getLabel(); - fragment.setHeader(icon, label, null); + fragment.setHeader(icon, label, null, true); fragment.setSummary(Utils.getPermissionGroupDescriptionString(fragment.getActivity(), groupName, permissionApps.getDescription()), null); @@ -407,7 +407,7 @@ public final class PermissionAppsFragment extends SettingsWithLargeHeader implem mOuterFragment = (PermissionAppsFragment) getTargetFragment(); setLoading(true /* loading */, false /* animate */); super.onCreate(savedInstanceState); - setHeader(mOuterFragment.mIcon, mOuterFragment.mLabel, null); + setHeader(mOuterFragment.mIcon, mOuterFragment.mLabel, null, true); if (mOuterFragment.mExtraScreen != null) { setPreferenceScreen(); } else { diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java index 105e1b0eb..d8d67f8cb 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java @@ -403,7 +403,7 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements setHeader(Utils.applyTint(context, context.getDrawable(group.getIconResId()), android.R.attr.colorControlNormal), context.getString(R.string.app_permission_usage_filter_label, - group.getLabel()), null); + group.getLabel()), null, true); setSummary(context.getString(R.string.app_permission_usage_remove_filter), v -> { mFilterGroup = null; // We already loaded all data, so don't reload @@ -558,7 +558,7 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements pref.setTitleIcons(Collections.singletonList(group.getIconResId())); pref.setKey(group.getApp().packageName + "," + group.getName()); pref.useSmallerIcon(); - pref.setRightIcon(context.getDrawable(R.drawable.ic_settings)); + pref.setRightIcon(context.getDrawable(R.drawable.ic_settings_accent)); return pref; } diff --git a/src/com/android/packageinstaller/permission/ui/handheld/SettingsWithLargeHeader.java b/src/com/android/packageinstaller/permission/ui/handheld/SettingsWithLargeHeader.java index e38d73eeb..e1b538ea0 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/SettingsWithLargeHeader.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/SettingsWithLargeHeader.java @@ -41,6 +41,7 @@ public abstract class SettingsWithLargeHeader extends PermissionsFrameFragment protected Intent mInfoIntent; protected Drawable mIcon; protected CharSequence mLabel; + protected boolean mSmallIcon; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, @@ -61,12 +62,14 @@ public abstract class SettingsWithLargeHeader extends PermissionsFrameFragment * @param icon the icon * @param label the label * @param infoIntent the intent to show on click + * @param smallIcon whether the icon should be small */ public void setHeader(@NonNull Drawable icon, @NonNull CharSequence label, - Intent infoIntent) { + Intent infoIntent, boolean smallIcon) { mIcon = icon; mLabel = label; mInfoIntent = infoIntent; + mSmallIcon = smallIcon; updateHeader(mHeader); } @@ -81,6 +84,12 @@ public abstract class SettingsWithLargeHeader extends PermissionsFrameFragment ImageView appIcon = header.requireViewById(R.id.entity_header_icon); appIcon.setImageDrawable(mIcon); + if (mSmallIcon) { + int size = getContext().getResources().getDimensionPixelSize( + R.dimen.permission_icon_header_size); + appIcon.getLayoutParams().width = size; + appIcon.getLayoutParams().height = size; + } TextView appName = header.requireViewById(R.id.entity_header_title); appName.setText(mLabel); -- GitLab From a9d894b8c3b5bf88268b1eeb269210e6709e4954 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Wed, 27 Mar 2019 15:31:59 -0700 Subject: [PATCH 505/701] Remove unused filter spinner file. Test: Open Permissions Hub. Change-Id: Ic66d5047ffc1b0b0c7168dade5e14e6710bc89c2 --- res/layout/single_spinner.xml | 33 --------------------------------- 1 file changed, 33 deletions(-) delete mode 100644 res/layout/single_spinner.xml diff --git a/res/layout/single_spinner.xml b/res/layout/single_spinner.xml deleted file mode 100644 index 716ea75c1..000000000 --- a/res/layout/single_spinner.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - -- GitLab From d6b33b14c5269a931e140e6f0619e4994e2b15d4 Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Wed, 27 Mar 2019 13:05:48 -0700 Subject: [PATCH 506/701] Add a bit of animation to request role dialog item. Otherwise the text view jumps around. Bug: 128713569 Test: manual Change-Id: I6fc684ae2014b5b5a5b603933ddf67ad1f89f53a --- res/layout/request_role_item.xml | 3 +++ .../packageinstaller/role/ui/RequestRoleFragment.java | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/res/layout/request_role_item.xml b/res/layout/request_role_item.xml index 285a31a34..de8195d57 100644 --- a/res/layout/request_role_item.xml +++ b/res/layout/request_role_item.xml @@ -23,6 +23,7 @@ android:minHeight="?android:listPreferredItemHeight" android:paddingStart="?android:listPreferredItemPaddingStart" android:paddingEnd="?android:listPreferredItemPaddingEnd" + android:clipChildren="false" android:gravity="center_vertical" android:orientation="horizontal"> @@ -32,10 +33,12 @@ android:layout_height="32dp" /> qualifyingApplication = getItem(position); @@ -518,12 +523,16 @@ public class RequestRoleFragment extends DialogFragment { @NonNull public final ImageView iconImage; @NonNull + public final ViewGroup titleAndSubtitleLayout; + @NonNull public final TextView titleText; @NonNull public final TextView subtitleText; ViewHolder(@NonNull View view) { iconImage = Objects.requireNonNull(view.findViewById(R.id.icon)); + titleAndSubtitleLayout = Objects.requireNonNull(view.findViewById( + R.id.title_and_subtitle)); titleText = Objects.requireNonNull(view.findViewById(R.id.title)); subtitleText = Objects.requireNonNull(view.findViewById(R.id.subtitle)); } -- GitLab From 35d169d0b92750c12c189efd4d9caabff8459cd1 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Thu, 28 Mar 2019 08:07:21 -0700 Subject: [PATCH 507/701] Properly check that usages are in the correct time range. In addition to passing the time range to the API that returns the usages, we also have to check that the returned usages are within the time period. Not doing this caused users of this API to show incorrect results. Test: See that Settings and PermissionsController have the same values in their bar charts. Change-Id: I5f39881dc8df04f9c954fb4b1102737fdd6aad6d --- .../service/PermissionControllerServiceImpl.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java b/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java index d06c74889..9c4cd35da 100644 --- a/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java +++ b/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java @@ -455,16 +455,13 @@ public final class PermissionControllerServiceImpl extends PermissionControllerS for (int appNum = 0; appNum < numApps; appNum++) { AppPermissionUsage appPermissionUsage = appPermissionUsages.get(appNum); - if (appPermissionUsage.getAccessCount() <= 0) { - continue; - } - List appGroups = appPermissionUsage.getGroupUsages(); int numGroups = appGroups.size(); for (int groupNum = 0; groupNum < numGroups; groupNum++) { GroupUsage groupUsage = appGroups.get(groupNum); - if (groupUsage.getAccessCount() <= 0) { + if (groupUsage.getAccessCount() <= 0 + || groupUsage.getLastAccessTime() < filterTimeBeginMillis) { continue; } if (!shouldShowPermission(this, groupUsage.getGroup())) { -- GitLab From 03af703038ec75c0da807bc5fd015844f514d884 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Thu, 28 Mar 2019 10:33:07 -0700 Subject: [PATCH 508/701] Do not reload Permissions Hub when going back. To solve this, I moved the call to reload the data so it does not happen when the Fragment is re-created. Dimply doing this caused the loader to re-report its results (making us redraw the screen anyway), so I stopped the loader. That required me to make a copy of its data. Fixes: 129429535 Test: Open Permissions Hub, click something, go back, see no reload. Test: Open permissions Hub, open filter by permission dialog, see all groups. Change-Id: I3510a90f5690f58b9ba18b41b6d13c4e172bed50 --- .../permission/model/PermissionUsages.java | 4 ++++ .../ui/handheld/PermissionUsageFragment.java | 24 ++++++++----------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/com/android/packageinstaller/permission/model/PermissionUsages.java b/src/com/android/packageinstaller/permission/model/PermissionUsages.java index fde235790..09026eb98 100644 --- a/src/com/android/packageinstaller/permission/model/PermissionUsages.java +++ b/src/com/android/packageinstaller/permission/model/PermissionUsages.java @@ -136,6 +136,10 @@ public final class PermissionUsages implements LoaderCallbacks mAppPermissionUsages; private Collator mCollator; @@ -192,6 +193,8 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements mCollator = Collator.getInstance( context.getResources().getConfiguration().getLocales().get(0)); mPermissionUsages = new PermissionUsages(context); + + reloadData(); } @Override @@ -199,13 +202,7 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements super.onStart(); getActivity().setTitle(R.string.permission_usage_title); - if (mFinishedInitialLoad) { - setProgressBarVisible(true); - } - hideHeader(); - - reloadData(); } /** @@ -350,6 +347,7 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements if (mPermissionUsages.getUsages().isEmpty()) { return; } + mAppPermissionUsages = new ArrayList<>(mPermissionUsages.getUsages()); // Use the saved permission group or the one passed as an argument, if applicable. if (mSavedGroupName != null && mFilterGroup == null) { @@ -368,9 +366,7 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements } private void updateUI() { - final List appPermissionUsages = - new ArrayList<>(mPermissionUsages.getUsages()); - if (appPermissionUsages.isEmpty() || getActivity() == null) { + if (mAppPermissionUsages.isEmpty() || getActivity() == null) { return; } Context context = getActivity(); @@ -391,9 +387,9 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements List> usages = new ArrayList<>(); mGroupAppCounts = new ArrayMap<>(); ArrayList permApps = new ArrayList<>(); - int numApps = appPermissionUsages.size(); + int numApps = mAppPermissionUsages.size(); for (int appNum = 0; appNum < numApps; appNum++) { - AppPermissionUsage appUsage = appPermissionUsages.get(appNum); + AppPermissionUsage appUsage = mAppPermissionUsages.get(appNum); boolean used = false; List appGroups = appUsage.getGroupUsages(); int numGroups = appGroups.size(); @@ -503,6 +499,7 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements setLoading(false, true); mFinishedInitialLoad = true; setProgressBarVisible(false); + mPermissionUsages.stopLoader(getActivity().getLoaderManager()); }).execute(permApps.toArray(new PermissionApps.PermissionApp[permApps.size()])); } @@ -786,10 +783,9 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements private @NonNull List getOSPermissionGroups() { final List groups = new ArrayList<>(); final Set seenGroups = new ArraySet<>(); - final List appUsages = mPermissionUsages.getUsages(); - final int numGroups = appUsages.size(); + final int numGroups = mAppPermissionUsages.size(); for (int i = 0; i < numGroups; i++) { - final AppPermissionUsage appUsage = appUsages.get(i); + final AppPermissionUsage appUsage = mAppPermissionUsages.get(i); final List groupUsages = appUsage.getGroupUsages(); final int groupUsageCount = groupUsages.size(); for (int j = 0; j < groupUsageCount; j++) { -- GitLab From bc136b90ad106a448b5f8f265d36074c21d86b85 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Thu, 28 Mar 2019 11:01:16 -0700 Subject: [PATCH 509/701] Correctly handle relative last access times of 0. This keeps relative times the same as absolute, which handle 0 the same way. Fixes: 129436944 Test: Hardcode access times of 0 and see the strings are the same. Change-Id: Ib999791c118e5aeabe3e18f68dd0108a07489805 --- src/com/android/packageinstaller/permission/utils/Utils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/android/packageinstaller/permission/utils/Utils.java b/src/com/android/packageinstaller/permission/utils/Utils.java index 8aa9e3f7b..bf062c226 100644 --- a/src/com/android/packageinstaller/permission/utils/Utils.java +++ b/src/com/android/packageinstaller/permission/utils/Utils.java @@ -551,7 +551,7 @@ public final class Utils { */ public static @Nullable String getRelativeLastUsageString(@NonNull Context context, @Nullable AppPermissionUsage.GroupUsage groupUsage) { - if (groupUsage == null) { + if (groupUsage == null || groupUsage.getLastAccessTime() == 0) { return null; } return getTimeDiffStr(context, System.currentTimeMillis() -- GitLab From 4cc42442eed4fadf24ecb992c16798646db40dd0 Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Wed, 27 Mar 2019 17:58:15 -0700 Subject: [PATCH 510/701] Add role description to Settings UI. Bug: 128713569 Test: manual Change-Id: I7283a1fbbe723e2be3b1518b684d55e5d40c15c6 --- res/drawable/ic_info_outline.xml | 44 +++++---- res/drawable/ic_info_outline_accent.xml | 24 +++++ res/layout/header.xml | 2 +- res/xml/roles.xml | 12 +++ .../packageinstaller/role/model/Role.java | 20 ++++- .../packageinstaller/role/model/Roles.java | 13 ++- .../role/ui/DefaultAppFragment.java | 13 +++ .../role/ui/FooterPreference.java | 89 +++++++++++++++++++ .../role/ui/SpecialAppAccessFragment.java | 15 +++- .../packageinstaller/role/utils/UiUtils.java | 60 +++++++++++++ 10 files changed, 264 insertions(+), 28 deletions(-) create mode 100644 res/drawable/ic_info_outline_accent.xml create mode 100644 src/com/android/packageinstaller/role/ui/FooterPreference.java diff --git a/res/drawable/ic_info_outline.xml b/res/drawable/ic_info_outline.xml index 86597586d..7b9e17e6a 100644 --- a/res/drawable/ic_info_outline.xml +++ b/res/drawable/ic_info_outline.xml @@ -1,24 +1,30 @@ - - 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. ---> - + android:fillColor="#FF000000" + android:pathData="M11,17h2v-6h-2v6zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM11,9h2L13,7h-2v2z"/> diff --git a/res/drawable/ic_info_outline_accent.xml b/res/drawable/ic_info_outline_accent.xml new file mode 100644 index 000000000..86597586d --- /dev/null +++ b/res/drawable/ic_info_outline_accent.xml @@ -0,0 +1,24 @@ + + + + diff --git a/res/layout/header.xml b/res/layout/header.xml index 45e6972c4..20687d7b5 100644 --- a/res/layout/header.xml +++ b/res/layout/header.xml @@ -47,7 +47,7 @@ android:minHeight="0dp" android:minWidth="0dp" android:scaleType="center" - android:src="@drawable/ic_info_outline" + android:src="@drawable/ic_info_outline_accent" android:contentDescription="@string/app_permissions_info_button_label" style="?android:attr/borderlessButtonStyle" /> diff --git a/res/xml/roles.xml b/res/xml/roles.xml index 16f50d747..1a06e8ff2 100644 --- a/res/xml/roles.xml +++ b/res/xml/roles.xml @@ -80,6 +80,7 @@ mPreferredActivities; - public Role(@NonNull String name, @Nullable RoleBehavior behavior, boolean exclusive, - @StringRes int labelResource, @StringRes int requestDescriptionResource, - @StringRes int requestTitleResource, @StringRes int shortLabelResource, - boolean showNone, boolean systemOnly, + public Role(@NonNull String name, @Nullable RoleBehavior behavior, + @StringRes int descriptionResource, boolean exclusive, @StringRes int labelResource, + @StringRes int requestDescriptionResource, @StringRes int requestTitleResource, + @StringRes int shortLabelResource, boolean showNone, boolean systemOnly, @NonNull List requiredComponents, @NonNull List permissions, @NonNull List appOps, @NonNull List preferredActivities) { mName = name; mBehavior = behavior; + mDescriptionResource = descriptionResource; mExclusive = exclusive; mLabelResource = labelResource; mRequestDescriptionResource = requestDescriptionResource; @@ -177,6 +184,11 @@ public class Role { return mBehavior; } + @StringRes + public int getDescriptionResource() { + return mDescriptionResource; + } + public boolean isExclusive() { return mExclusive; } diff --git a/src/com/android/packageinstaller/role/model/Roles.java b/src/com/android/packageinstaller/role/model/Roles.java index c46811e10..80fedd51b 100644 --- a/src/com/android/packageinstaller/role/model/Roles.java +++ b/src/com/android/packageinstaller/role/model/Roles.java @@ -309,6 +309,13 @@ public class Roles { behavior = null; } + Integer descriptionResource = requireAttributeResourceValue(parser, ATTRIBUTE_DESCRIPTION, + 0, TAG_ROLE); + if (descriptionResource == null) { + skipCurrentTag(parser); + return null; + } + Boolean exclusive = requireAttributeBooleanValue(parser, ATTRIBUTE_EXCLUSIVE, true, TAG_ROLE); if (exclusive == null) { @@ -418,9 +425,9 @@ public class Roles { if (preferredActivities == null) { preferredActivities = Collections.emptyList(); } - return new Role(name, behavior, exclusive, labelResource, requestDescriptionResource, - requestTitleResource, shortLabelResource, showNone, systemOnly, requiredComponents, - permissions, appOps, preferredActivities); + return new Role(name, behavior, descriptionResource, exclusive, labelResource, + requestDescriptionResource, requestTitleResource, shortLabelResource, showNone, + systemOnly, requiredComponents, permissions, appOps, preferredActivities); } @NonNull diff --git a/src/com/android/packageinstaller/role/ui/DefaultAppFragment.java b/src/com/android/packageinstaller/role/ui/DefaultAppFragment.java index 330df7bc7..e11b81fa7 100644 --- a/src/com/android/packageinstaller/role/ui/DefaultAppFragment.java +++ b/src/com/android/packageinstaller/role/ui/DefaultAppFragment.java @@ -56,6 +56,9 @@ public class DefaultAppFragment extends SettingsFragment private static final String PREFERENCE_KEY_NONE = DefaultAppFragment.class.getName() + ".preference.NONE"; + private static final String PREFERENCE_KEY_DESCRIPTION = DefaultAppFragment.class.getName() + + ".preference.DESCRIPTION"; + private String mRoleName; private UserHandle mUser; @@ -119,11 +122,13 @@ public class DefaultAppFragment extends SettingsFragment Context context = preferenceManager.getContext(); PreferenceScreen preferenceScreen = getPreferenceScreen(); + Preference oldDescriptionPreference = null; ArrayMap oldPreferences = new ArrayMap<>(); if (preferenceScreen == null) { preferenceScreen = preferenceManager.createPreferenceScreen(context); setPreferenceScreen(preferenceScreen); } else { + oldDescriptionPreference = preferenceScreen.findPreference(PREFERENCE_KEY_DESCRIPTION); for (int i = preferenceScreen.getPreferenceCount() - 1; i >= 0; --i) { Preference preference = preferenceScreen.getPreference(i); @@ -153,6 +158,14 @@ public class DefaultAppFragment extends SettingsFragment oldPreferences, preferenceScreen, context); } + Preference descriptionPreference = oldDescriptionPreference; + if (descriptionPreference == null) { + descriptionPreference = new FooterPreference(context); + descriptionPreference.setKey(PREFERENCE_KEY_DESCRIPTION); + descriptionPreference.setSummary(mRole.getDescriptionResource()); + } + preferenceScreen.addPreference(descriptionPreference); + updateState(); } diff --git a/src/com/android/packageinstaller/role/ui/FooterPreference.java b/src/com/android/packageinstaller/role/ui/FooterPreference.java new file mode 100644 index 000000000..4c8a84496 --- /dev/null +++ b/src/com/android/packageinstaller/role/ui/FooterPreference.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2019 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.packageinstaller.role.ui; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.Gravity; +import android.view.ViewGroup; +import android.widget.LinearLayout; + +import androidx.annotation.AttrRes; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.StyleRes; +import androidx.preference.Preference; +import androidx.preference.PreferenceViewHolder; + +import com.android.packageinstaller.role.utils.UiUtils; +import com.android.permissioncontroller.R; + +/** + * {@link Preference} acting as the footer of a page. + */ +public class FooterPreference extends Preference { + + private static final int ICON_LAYOUT_PADDING_VERTICAL_DP = 16; + + public FooterPreference(@NonNull Context context, @Nullable AttributeSet attrs, + @AttrRes int defStyleAttr, @StyleRes int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + + init(); + } + + public FooterPreference(@NonNull Context context, @Nullable AttributeSet attrs, + @AttrRes int defStyleAttr) { + super(context, attrs, defStyleAttr); + + init(); + } + + public FooterPreference(@NonNull Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + + init(); + } + + public FooterPreference(@NonNull Context context) { + super(context); + + init(); + } + + private void init() { + setIcon(R.drawable.ic_info_outline); + setSelectable(false); + } + + @Override + public void onBindViewHolder(@NonNull PreferenceViewHolder holder) { + super.onBindViewHolder(holder); + + holder.setDividerAllowedAbove(true); + + ViewGroup iconLayout = (ViewGroup) holder.findViewById(R.id.icon_frame); + LinearLayout.LayoutParams iconLayoutParams = (LinearLayout.LayoutParams) + iconLayout.getLayoutParams(); + iconLayoutParams.gravity = Gravity.TOP; + iconLayout.setLayoutParams(iconLayoutParams); + int iconLayoutPaddingVertical = UiUtils.dpToPxOffset(ICON_LAYOUT_PADDING_VERTICAL_DP, + iconLayout.getContext()); + iconLayout.setPaddingRelative(iconLayout.getPaddingStart(), iconLayoutPaddingVertical, + iconLayout.getPaddingEnd(), iconLayoutPaddingVertical); + } +} diff --git a/src/com/android/packageinstaller/role/ui/SpecialAppAccessFragment.java b/src/com/android/packageinstaller/role/ui/SpecialAppAccessFragment.java index f6576e56a..c7461e6a6 100644 --- a/src/com/android/packageinstaller/role/ui/SpecialAppAccessFragment.java +++ b/src/com/android/packageinstaller/role/ui/SpecialAppAccessFragment.java @@ -50,7 +50,10 @@ public class SpecialAppAccessFragment extends SettingsFragment private static final String LOG_TAG = SpecialAppAccessFragment.class.getSimpleName(); private static final String PREFERENCE_EXTRA_APPLICATION_INFO = - "com.android.packageinstaller.role.ui.extra.APPLICATION_INFO"; + SpecialAppAccessFragment.class.getName() + ".extra.APPLICATION_INFO"; + + private static final String PREFERENCE_KEY_DESCRIPTION = + SpecialAppAccessFragment.class.getName() + ".preference.DESCRIPTION"; private String mRoleName; @@ -108,11 +111,13 @@ public class SpecialAppAccessFragment extends SettingsFragment Context context = preferenceManager.getContext(); PreferenceScreen preferenceScreen = getPreferenceScreen(); + Preference oldDescriptionPreference = null; ArrayMap oldPreferences = new ArrayMap<>(); if (preferenceScreen == null) { preferenceScreen = preferenceManager.createPreferenceScreen(context); setPreferenceScreen(preferenceScreen); } else { + oldDescriptionPreference = preferenceScreen.findPreference(PREFERENCE_KEY_DESCRIPTION); for (int i = preferenceScreen.getPreferenceCount() - 1; i >= 0; --i) { Preference preference = preferenceScreen.getPreference(i); @@ -148,6 +153,14 @@ public class SpecialAppAccessFragment extends SettingsFragment preferenceScreen.addPreference(preference); } + Preference descriptionPreference = oldDescriptionPreference; + if (descriptionPreference == null) { + descriptionPreference = new FooterPreference(context); + descriptionPreference.setKey(PREFERENCE_KEY_DESCRIPTION); + descriptionPreference.setSummary(mRole.getDescriptionResource()); + } + preferenceScreen.addPreference(descriptionPreference); + updateState(); } diff --git a/src/com/android/packageinstaller/role/utils/UiUtils.java b/src/com/android/packageinstaller/role/utils/UiUtils.java index ded3e7fc9..b13010931 100644 --- a/src/com/android/packageinstaller/role/utils/UiUtils.java +++ b/src/com/android/packageinstaller/role/utils/UiUtils.java @@ -18,11 +18,16 @@ package com.android.packageinstaller.role.utils; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; +import android.content.Context; +import android.util.DisplayMetrics; +import android.util.TypedValue; import android.view.View; import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; +import androidx.annotation.Dimension; import androidx.annotation.NonNull; +import androidx.annotation.Px; /** * Utility methods about UI. @@ -31,6 +36,61 @@ public class UiUtils { private UiUtils() {} + /** + * Convert a dimension value in density independent pixels to pixels. + * + * @param dp the dimension value in density independent pixels + * @param context the context to get the {@link DisplayMetrics} + * @return the pixels + * + * @see TypedValue#complexToDimension(int, DisplayMetrics) + */ + @Dimension + public static float dpToPx(@Dimension(unit = Dimension.DP) float dp, @NonNull Context context) { + DisplayMetrics metrics = context.getResources().getDisplayMetrics(); + return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, metrics); + } + + /** + * Convert a dimension value in density independent pixels to an integer pixel offset. + * + * @param dp the dimension value in density independent pixels + * @param context the context to get the {@link DisplayMetrics} + * @return the integer pixel offset + * + * @see TypedValue#complexToDimensionPixelOffset(int, DisplayMetrics) + */ + @Px + public static int dpToPxOffset(@Dimension(unit = Dimension.DP) float dp, + @NonNull Context context) { + return (int) dpToPx(dp, context); + } + + /** + * Convert a dimension value in density independent pixels to an integer pixel size. + * + * @param dp the dimension value in density independent pixels + * @param context the context to get the {@link DisplayMetrics} + * @return the integer pixel size + * + * @see TypedValue#complexToDimensionPixelSize(int, DisplayMetrics) + */ + @Px + public static int dpToPxSize(@Dimension(unit = Dimension.DP) float dp, + @NonNull Context context) { + float value = dpToPx(dp, context); + int size = (int) (value >= 0 ? value + 0.5f : value - 0.5f); + if (size != 0) { + return size; + } else if (value == 0) { + return 0; + } else if (value > 0) { + return 1; + } else { + return -1; + } + } + /** * Set whether a view is shown. * -- GitLab From bf67844dd0d1aa437d8552c5047677439a38bd09 Mon Sep 17 00:00:00 2001 From: Joe Onorato Date: Sun, 24 Mar 2019 15:59:52 -0700 Subject: [PATCH 511/701] Let PermissionController display images during incident report confirmation. Test: bit GooglePermissionControllerTest:* GtsIncidentManagerTestCases:* Bug: 126192301 Change-Id: Ice66eefed92d7c7111ef4431e687bb125c53c721 --- OWNERS | 3 + PermissionController.mk | 4 +- res/layout/incident_image_confirmation.xml | 56 +++++ res/values/dimens.xml | 4 + res/values/strings.xml | 4 + .../incident/ConfirmationActivity.java | 218 +++++++++++++++++- .../incident/incident_minimal.proto | 57 +++++ .../incident/RequestConfirmationTest.java | 18 ++ 8 files changed, 352 insertions(+), 12 deletions(-) create mode 100644 res/layout/incident_image_confirmation.xml create mode 100644 src/com/android/packageinstaller/incident/incident_minimal.proto diff --git a/OWNERS b/OWNERS index d79854830..021a6c2d2 100644 --- a/OWNERS +++ b/OWNERS @@ -8,3 +8,6 @@ eugenesusla@google.com # For automotive related changes stenning@google.com davidln@google.com + +# For incident report related changes +joeo@google.com diff --git a/PermissionController.mk b/PermissionController.mk index 4d5b4e78c..d101fdb9b 100644 --- a/PermissionController.mk +++ b/PermissionController.mk @@ -6,7 +6,8 @@ LOCAL_USE_AAPT2 := true LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES := \ - $(call all-java-files-under, src) + $(call all-java-files-under, src) \ + $(call all-proto-files-under, src) LOCAL_STATIC_ANDROID_LIBRARIES += \ iconloader \ @@ -42,6 +43,7 @@ LOCAL_SDK_VERSION := system_current LOCAL_MIN_SDK_VERSION := 28 LOCAL_PRIVILEGED_MODULE := true LOCAL_CERTIFICATE := platform +LOCAL_PROTOC_OPTIMIZE_TYPE := lite LOCAL_PROGUARD_FLAG_FILES := proguard.flags diff --git a/res/layout/incident_image_confirmation.xml b/res/layout/incident_image_confirmation.xml new file mode 100644 index 000000000..8659756ce --- /dev/null +++ b/res/layout/incident_image_confirmation.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + diff --git a/res/values/dimens.xml b/res/values/dimens.xml index f881242a6..f5f1704dc 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -51,4 +51,8 @@ 32dp 16dp + + 150dp + 200dp + diff --git a/res/values/strings.xml b/res/values/strings.xml index d156ba858..4bc53cf39 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -784,6 +784,10 @@ Allow %4$s to upload a bug report?" + + "There was an error processing the bug report for %1$s. So sharing the detailed debugging data data has been denied. Sorry for the interruption." + Allow diff --git a/src/com/android/packageinstaller/incident/ConfirmationActivity.java b/src/com/android/packageinstaller/incident/ConfirmationActivity.java index 2dfdcec48..724c34ecb 100644 --- a/src/com/android/packageinstaller/incident/ConfirmationActivity.java +++ b/src/com/android/packageinstaller/incident/ConfirmationActivity.java @@ -21,18 +21,31 @@ import android.app.AlertDialog; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.content.DialogInterface.OnDismissListener; +import android.content.res.Resources; +import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; import android.os.IncidentManager; import android.util.Log; +import android.view.View; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; import com.android.permissioncontroller.R; +import com.google.protobuf.ByteString; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; + /** * Confirmation dialog for approving an incident or bug report for sharing off the device. */ public class ConfirmationActivity extends Activity implements OnClickListener, OnDismissListener { - private static final String TAG = ConfirmationActivity.class.getSimpleName(); + private static final String TAG = "ConfirmationActivity"; /** * Currently displaying activity. @@ -77,20 +90,75 @@ public class ConfirmationActivity extends Activity implements OnClickListener, O return; } - final IncidentManager.PendingReport report = new IncidentManager.PendingReport(uri); - final String appLabel = formatting.getAppLabel(report.getRequestingPackage()); + final IncidentManager.PendingReport pending = new IncidentManager.PendingReport(uri); + final String appLabel = formatting.getAppLabel(pending.getRequestingPackage()); + + final Resources res = getResources(); + final ArrayList images = getImages(uri, res); + if (images == null) { + // Null result from getImages means that there was an error in the input, + // and we will just summarily reject the upload, since we can't get proper + // approval. + // Zero-length list means that we will proceed with the imageless consent + // dialog. + final IncidentManager incidentManager = getSystemService(IncidentManager.class); + incidentManager.denyReport(getIntent().getData()); - new AlertDialog.Builder(this) + // Show a message to the user saying... nevermind. + new AlertDialog.Builder(this) .setTitle(R.string.incident_report_dialog_title) - .setMessage(getString(R.string.incident_report_dialog_text, - appLabel, - formatting.getDate(report.getTimestamp()), - formatting.getTime(report.getTimestamp()), - appLabel)) - .setPositiveButton(R.string.incident_report_dialog_allow_label, this) - .setNegativeButton(R.string.incident_report_dialog_deny_label, this) + .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + finish(); + } + }) + .setMessage(getString(R.string.incident_report_error_dialog_text, appLabel)) .setOnDismissListener(this) .show(); + return; + } + + + final AlertDialog.Builder builder = new AlertDialog.Builder(this) + .setTitle(R.string.incident_report_dialog_title) + .setPositiveButton(R.string.incident_report_dialog_allow_label, this) + .setNegativeButton(R.string.incident_report_dialog_deny_label, this) + .setOnDismissListener(this); + + final String message = getString(R.string.incident_report_dialog_text, + appLabel, + formatting.getDate(pending.getTimestamp()), + formatting.getTime(pending.getTimestamp()), + appLabel); + + + final int imagesSize = images.size(); + if (imagesSize > 0) { + final View content = getLayoutInflater().inflate(R.layout.incident_image_confirmation, + null); + final LinearLayout imageList = (LinearLayout) content.findViewById(R.id.imageList); + + final int width = res.getDimensionPixelSize(R.dimen.incident_image_width); + final int height = res.getDimensionPixelSize(R.dimen.incident_image_height); + + for (int i = 0; i < imagesSize; i++) { + final Drawable drawable = images.get(i); + final ImageView imageView = new ImageView(this); + imageView.setImageDrawable(images.get(i)); + imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE); + + imageList.addView(imageView, new LinearLayout.LayoutParams(width, height)); + } + + ((TextView) content.findViewById(R.id.message)).setText(message); + + builder.setView(content); + } else { + builder.setMessage(message); + } + + builder.show(); } /** @@ -140,5 +208,133 @@ public class ConfirmationActivity extends Activity implements OnClickListener, O } finish(); } + + ArrayList getImages(final Uri uri, Resources res) { + try { + final IncidentManager incidentManager = getSystemService(IncidentManager.class); + final IncidentManager.IncidentReport report = incidentManager.getIncidentReport(uri); + + final InputStream stream = report.getInputStream(); + if (stream != null) { + return getImages(stream, res); + } + } catch (IOException ex) { + Log.w(TAG, "Error while reading stream. The report will be rejected.", ex); + return null; + } catch (OutOfMemoryError ex) { + Log.w(TAG, "Out of memory while creating confirmation images. The report will" + + " be rejected.", ex); + return null; + } + return new ArrayList(); + } + + ArrayList getImages(InputStream stream, Resources res) throws IOException { + final IncidentMinimal incident = IncidentMinimal.parseFrom(stream); + if (incident != null) { + return getImages(incident, res); + } else { + return new ArrayList(); + } + } + + ArrayList getImages(IncidentMinimal incident, Resources res) { + final ArrayList drawables = new ArrayList(); + + final int totalImageCountLimit = 20; + int totalImageCount = 0; + + if (incident.hasRestrictedImagesSection()) { + final RestrictedImagesDumpProto section = incident.getRestrictedImagesSection(); + final int setsCount = section.getSetsCount(); + for (int i = 0; i < setsCount; i++) { + final RestrictedImageSetProto set = section.getSets(i); + if (set == null) { + continue; + } + final int imageCount = set.getImagesCount(); + for (int j = 0; j < imageCount; j++) { + // Hard cap on number of images, as a guardrail. + totalImageCount++; + if (totalImageCount > totalImageCountLimit) { + Log.w(TAG, "Image count is greater than the limit of " + + totalImageCountLimit + ". The report will be rejected."); + return null; + } + + final RestrictedImageProto image = set.getImages(j); + if (image == null) { + continue; + } + final String mimeType = image.getMimeType(); + if (!("image/jpeg".equals(mimeType) + || "image/png".equals(mimeType))) { + Log.w(TAG, "Unsupported image type " + mimeType + + ". The report will be rejected."); + return null; + } + final ByteString bytes = image.getImageData(); + if (bytes == null) { + continue; + } + final byte[] buf = bytes.toByteArray(); + if (buf.length == 0) { + continue; + } + + // This will attempt to uncompress the image. If it's gigantic, + // this could fail with OutOfMemoryError, which will be caught + // by the caller, and turned into a report rejection. + final Drawable drawable = new android.graphics.drawable.BitmapDrawable( + res, new ByteArrayInputStream(buf)); + + // TODO: Scale bitmap to correct thumbnail size to save memory. + + drawables.add(drawable); + } + } + } + + // Test data + if (true) { + drawables.add(new android.graphics.drawable.BitmapDrawable(res, + new ByteArrayInputStream(new byte[] { + // png image data + -119, 80, 78, 71, 13, 10, 26, 10, + 0, 0, 0, 13, 73, 72, 68, 82, + 0, 0, 0, 100, 0, 0, 0, 100, + 1, 3, 0, 0, 0, 74, 44, 7, + 23, 0, 0, 0, 4, 103, 65, 77, + 65, 0, 0, -79, -113, 11, -4, 97, + 5, 0, 0, 0, 1, 115, 82, 71, + 66, 0, -82, -50, 28, -23, 0, 0, + 0, 6, 80, 76, 84, 69, -1, -1, + -1, 0, 0, 0, 85, -62, -45, 126, + 0, 0, 0, -115, 73, 68, 65, 84, + 56, -53, -19, -46, -79, 17, -128, 32, + 12, 5, -48, 120, 22, -106, -116, -32, + 40, -84, 101, -121, -93, 57, 10, 35, + 88, 82, 112, 126, 3, -60, 104, 6, + -112, 70, 127, -59, -69, -53, 29, 33, + -127, -24, 79, -49, -52, -15, 41, 36, + 34, -105, 85, 124, -14, 88, 27, 6, + 28, 68, 1, 82, 62, 22, -95, -108, + 55, -95, 40, -9, -110, -12, 98, -107, + 76, -41, -105, -62, -50, 111, -60, 46, + -14, -4, 24, -89, 42, -103, 16, 63, + -72, -11, -15, 48, -62, 102, -44, 102, + -73, -56, 56, -21, -128, 92, -70, -124, + 117, -46, -67, -77, 82, 80, 121, -44, + -56, 116, 93, -45, -90, -5, -29, -24, + -83, -75, 52, -34, 55, -22, 102, -21, + -105, -124, -23, 71, 87, -7, -25, -59, + -100, -73, -92, -122, -7, -109, -49, -80, + -89, 0, 0, 0, 0, 73, 69, 78, + 68, -82, 66, 96, -126 + }))); + } + + return drawables; + } } diff --git a/src/com/android/packageinstaller/incident/incident_minimal.proto b/src/com/android/packageinstaller/incident/incident_minimal.proto new file mode 100644 index 000000000..29088f846 --- /dev/null +++ b/src/com/android/packageinstaller/incident/incident_minimal.proto @@ -0,0 +1,57 @@ +/* + * 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. + */ + +syntax = "proto2"; +package com.android.packageinstaller.incident; + +option java_multiple_files = true; + +/** + * This message has the same fields in an incident report that we care about + * but none of the ones we don't. So when we receive one, we attempt to parse + * it using this proto, which will result in the rest of the fields being dropped. + */ +message IncidentMinimal { + optional RestrictedImagesDumpProto restricted_images_section = 3025; +} + +message RestrictedImagesDumpProto { + repeated RestrictedImageSetProto sets = 1; +} + +message RestrictedImageSetProto { + // Name of the service producing the data. + optional string category = 1; + + // The images + repeated RestrictedImageProto images = 2; + + // Additional metadata + optional bytes metadata = 3; +} + +message RestrictedImageProto { + // Type of image data + optional string mime_type = 1; + + // The image data + optional bytes image_data = 2; + + // Metadata about the image. Typically this has another proto schema, + // but it is undefined exactly what that is in AOSP code. + optional bytes metadata = 3; +} + diff --git a/test/instrumentation/src/com/android/permissioncontrollertesthelper/incident/RequestConfirmationTest.java b/test/instrumentation/src/com/android/permissioncontrollertesthelper/incident/RequestConfirmationTest.java index 347ef170e..072eb1af4 100644 --- a/test/instrumentation/src/com/android/permissioncontrollertesthelper/incident/RequestConfirmationTest.java +++ b/test/instrumentation/src/com/android/permissioncontrollertesthelper/incident/RequestConfirmationTest.java @@ -275,6 +275,24 @@ public class RequestConfirmationTest { runTestFlow(false, Status.TIMED_OUT); } + /** + * Test that creating the drawables in ConfirmationActivity will fail if we + * do it with too many images. + */ + @Test + public void testTooManyImages() { + // TODO(b/129485788) + } + + /** + * Test that creating the drawables in ConfirmationActivity will fail if we + * do it with not too many images but with images that are too big. + */ + @Test + public void testTooBigImages() { + // TODO(b/129485788) + } + public static final void main(String[] args) { Log.d(TAG, "RequestConfirmationTest args=" + java.util.Arrays.toString(args)); System.out.println("RequestConfirmationTest args=" + java.util.Arrays.toString(args)); -- GitLab From 08e1271b04e0bcff52fed90530b13238eca6334b Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Thu, 28 Mar 2019 13:42:22 -0700 Subject: [PATCH 512/701] Fix text in ongoing usage dialog in RTL locales. Fixes: 129479959 Test: View dialog in RTL and LTR locales. Change-Id: I14bbd564b2dc89d3858d49e25d50ad3a97e1ed69 --- res/values/styles.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/res/values/styles.xml b/res/values/styles.xml index 1cf1b0c70..bb560b2a4 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -469,6 +469,7 @@ match_parent 1 start|center_vertical + locale 16sp 16dp -- GitLab From 059640e4c0799c0b11bf45ba418a6b5bf8fbef20 Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Thu, 28 Mar 2019 15:29:40 -0700 Subject: [PATCH 513/701] Add settings button for home role. This was in DefaultHomePreferenceController. Bug: 128713569 Test: manual Change-Id: I98fc78c3700a871ee223d53fea227047f023589d --- res/drawable/ic_info_outline.xml | 4 +- ...ngs_accent.xml => ic_settings_outline.xml} | 0 res/drawable/ic_settings_outline_accent.xml | 34 ++++++ ...xml => radio_button_preference_widget.xml} | 0 .../settings_button_preference_widget.xml | 43 +++++++ res/layout/two_target_preference.xml | 31 +++++ res/values/strings.xml | 3 + .../ui/handheld/PermissionUsageFragment.java | 2 +- .../role/model/HomeRoleBehavior.java | 36 ++++++ .../packageinstaller/role/model/Role.java | 15 +++ .../role/model/RoleBehavior.java | 9 ++ .../ui/AppIconSettingsButtonPreference.java | 71 +++++++++++ .../role/ui/DefaultAppListFragment.java | 6 +- .../role/ui/FooterPreference.java | 20 ++-- .../role/ui/RadioButtonPreference.java | 19 +-- .../role/ui/SettingsButtonPreference.java | 113 ++++++++++++++++++ .../role/ui/SpecialAppAccessFragment.java | 3 + .../role/ui/SpecialAppAccessListFragment.java | 7 +- .../role/ui/TwoTargetPreference.java | 82 +++++++++++++ 19 files changed, 473 insertions(+), 25 deletions(-) rename res/drawable/{ic_settings_accent.xml => ic_settings_outline.xml} (100%) create mode 100644 res/drawable/ic_settings_outline_accent.xml rename res/layout/{preference_widget_radio_button.xml => radio_button_preference_widget.xml} (100%) create mode 100644 res/layout/settings_button_preference_widget.xml create mode 100644 res/layout/two_target_preference.xml create mode 100644 src/com/android/packageinstaller/role/ui/AppIconSettingsButtonPreference.java create mode 100644 src/com/android/packageinstaller/role/ui/SettingsButtonPreference.java create mode 100644 src/com/android/packageinstaller/role/ui/TwoTargetPreference.java diff --git a/res/drawable/ic_info_outline.xml b/res/drawable/ic_info_outline.xml index 7b9e17e6a..b57df4495 100644 --- a/res/drawable/ic_info_outline.xml +++ b/res/drawable/ic_info_outline.xml @@ -22,9 +22,9 @@ android:height="24dp" android:viewportWidth="24" android:viewportHeight="24" - android:tint="?android:attr/colorControlNormal"> + android:tint="?android:colorControlNormal"> + android:pathData="M11,17h2v-6h-2v6zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM11,9h2L13,7h-2v2z" /> diff --git a/res/drawable/ic_settings_accent.xml b/res/drawable/ic_settings_outline.xml similarity index 100% rename from res/drawable/ic_settings_accent.xml rename to res/drawable/ic_settings_outline.xml diff --git a/res/drawable/ic_settings_outline_accent.xml b/res/drawable/ic_settings_outline_accent.xml new file mode 100644 index 000000000..06aefa8d1 --- /dev/null +++ b/res/drawable/ic_settings_outline_accent.xml @@ -0,0 +1,34 @@ + + + + + + + + + + diff --git a/res/layout/preference_widget_radio_button.xml b/res/layout/radio_button_preference_widget.xml similarity index 100% rename from res/layout/preference_widget_radio_button.xml rename to res/layout/radio_button_preference_widget.xml diff --git a/res/layout/settings_button_preference_widget.xml b/res/layout/settings_button_preference_widget.xml new file mode 100644 index 000000000..bd1d29b2c --- /dev/null +++ b/res/layout/settings_button_preference_widget.xml @@ -0,0 +1,43 @@ + + + + + + + + + + diff --git a/res/layout/two_target_preference.xml b/res/layout/two_target_preference.xml new file mode 100644 index 000000000..4e3fce9e7 --- /dev/null +++ b/res/layout/two_target_preference.xml @@ -0,0 +1,31 @@ + + + + + + + + + diff --git a/res/values/strings.xml b/res/values/strings.xml index 34c8a2d5f..b58c0a60f 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -712,6 +712,9 @@ \u0020and\u0020 + + Settings + Default apps diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java index 7c7fbdcca..7e5b1b791 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java @@ -662,7 +662,7 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements pref.setTitleIcons(Collections.singletonList(group.getIconResId())); pref.setKey(group.getApp().packageName + "," + group.getName()); pref.useSmallerIcon(); - pref.setRightIcon(context.getDrawable(R.drawable.ic_settings_accent)); + pref.setRightIcon(context.getDrawable(R.drawable.ic_settings_outline)); return pref; } diff --git a/src/com/android/packageinstaller/role/model/HomeRoleBehavior.java b/src/com/android/packageinstaller/role/model/HomeRoleBehavior.java index 9c18fe368..1fcf1774d 100644 --- a/src/com/android/packageinstaller/role/model/HomeRoleBehavior.java +++ b/src/com/android/packageinstaller/role/model/HomeRoleBehavior.java @@ -16,19 +16,25 @@ package com.android.packageinstaller.role.model; +import android.app.role.RoleManager; +import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; +import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.Build; import android.os.UserHandle; import android.provider.Settings; +import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.preference.Preference; +import com.android.packageinstaller.permission.utils.CollectionUtils; +import com.android.packageinstaller.role.ui.SettingsButtonPreference; import com.android.packageinstaller.role.utils.UserUtils; import com.android.permissioncontroller.R; @@ -44,6 +50,8 @@ import java.util.Objects; */ public class HomeRoleBehavior implements RoleBehavior { + private static final String LOG_TAG = HomeRoleBehavior.class.getSimpleName(); + @Override public boolean isAvailableAsUser(@NonNull Role role, @NonNull UserHandle user, @NonNull Context context) { @@ -90,6 +98,34 @@ public class HomeRoleBehavior implements RoleBehavior { return VisibilityMixin.isVisible("config_showDefaultHome", context); } + @Override + public void preparePreferenceAsUser(@NonNull Role role, + @NonNull SettingsButtonPreference preference, @NonNull UserHandle user, + @NonNull Context context) { + SettingsButtonPreference.OnSettingsButtonClickListener listener = null; + RoleManager roleManager = context.getSystemService(RoleManager.class); + String packageName = CollectionUtils.firstOrNull(roleManager.getRoleHoldersAsUser( + role.getName(), user)); + if (packageName != null) { + Intent intent = new Intent(Intent.ACTION_APPLICATION_PREFERENCES) + .setPackage(packageName) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); + PackageManager userPackageManager = UserUtils.getUserContext(context, user) + .getPackageManager(); + ActivityInfo activityInfo = intent.resolveActivityInfo(userPackageManager, 0); + if (activityInfo != null && activityInfo.exported) { + listener = preference2 -> { + try { + context.startActivity(intent); + } catch (ActivityNotFoundException e) { + Log.e(LOG_TAG, "Cannot start activity for home app preferences", e); + } + }; + } + } + preference.setOnSettingsButtonClickListener(listener); + } + @Override public void prepareApplicationPreferenceAsUser(@NonNull Role role, @NonNull Preference preference, @NonNull ApplicationInfo applicationInfo, diff --git a/src/com/android/packageinstaller/role/model/Role.java b/src/com/android/packageinstaller/role/model/Role.java index c498457a1..d5cd7cbd7 100644 --- a/src/com/android/packageinstaller/role/model/Role.java +++ b/src/com/android/packageinstaller/role/model/Role.java @@ -35,6 +35,7 @@ import androidx.preference.Preference; import com.android.packageinstaller.Constants; import com.android.packageinstaller.permission.utils.Utils; +import com.android.packageinstaller.role.ui.SettingsButtonPreference; import com.android.packageinstaller.role.utils.PackageUtils; import com.android.packageinstaller.role.utils.UserUtils; @@ -341,6 +342,20 @@ public class Role { return null; } + /** + * Prepare a {@link Preference} for this role. + * + * @param preference the {@link Preference} for this role + * @param user the user for this role + * @param context the {@code Context} to retrieve system services + */ + public void preparePreferenceAsUser(@NonNull SettingsButtonPreference preference, + @NonNull UserHandle user, @NonNull Context context) { + if (mBehavior != null) { + mBehavior.preparePreferenceAsUser(this, preference, user, context); + } + } + /** * Prepare a {@link Preference} for an application. * diff --git a/src/com/android/packageinstaller/role/model/RoleBehavior.java b/src/com/android/packageinstaller/role/model/RoleBehavior.java index fa672f483..4701c20e1 100644 --- a/src/com/android/packageinstaller/role/model/RoleBehavior.java +++ b/src/com/android/packageinstaller/role/model/RoleBehavior.java @@ -25,6 +25,8 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.preference.Preference; +import com.android.packageinstaller.role.ui.SettingsButtonPreference; + import java.util.Collections; import java.util.List; @@ -74,6 +76,13 @@ public interface RoleBehavior { return null; } + /** + * @see Role#preparePreferenceAsUser(SettingsButtonPreference, UserHandle, Context) + */ + default void preparePreferenceAsUser(@NonNull Role role, + @NonNull SettingsButtonPreference preference, @NonNull UserHandle user, + @NonNull Context context) {} + /** * @see Role#prepareApplicationPreferenceAsUser(Preference, ApplicationInfo, UserHandle, * Context) diff --git a/src/com/android/packageinstaller/role/ui/AppIconSettingsButtonPreference.java b/src/com/android/packageinstaller/role/ui/AppIconSettingsButtonPreference.java new file mode 100644 index 000000000..a6dd496c2 --- /dev/null +++ b/src/com/android/packageinstaller/role/ui/AppIconSettingsButtonPreference.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2019 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.packageinstaller.role.ui; + +import android.content.Context; +import android.util.AttributeSet; + +import androidx.annotation.AttrRes; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.StyleRes; +import androidx.preference.PreferenceViewHolder; + +/** + * {@link SettingsButtonPreference} with {@link AppIconPreference.Mixin}. + */ +public class AppIconSettingsButtonPreference extends SettingsButtonPreference { + + private AppIconPreference.Mixin mMixin; + + public AppIconSettingsButtonPreference(@NonNull Context context, @Nullable AttributeSet attrs, + @AttrRes int defStyleAttr, @StyleRes int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + + init(); + } + + public AppIconSettingsButtonPreference(@NonNull Context context, @Nullable AttributeSet attrs, + @AttrRes int defStyleAttr) { + super(context, attrs, defStyleAttr); + + init(); + } + + public AppIconSettingsButtonPreference(@NonNull Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + + init(); + } + + public AppIconSettingsButtonPreference(@NonNull Context context) { + super(context); + + init(); + } + + private void init() { + mMixin = new AppIconPreference.Mixin(getContext()); + } + + @Override + public void onBindViewHolder(@NonNull PreferenceViewHolder holder) { + super.onBindViewHolder(holder); + + mMixin.onBindViewHolder(holder); + } +} diff --git a/src/com/android/packageinstaller/role/ui/DefaultAppListFragment.java b/src/com/android/packageinstaller/role/ui/DefaultAppListFragment.java index 968464be1..0d85abe22 100644 --- a/src/com/android/packageinstaller/role/ui/DefaultAppListFragment.java +++ b/src/com/android/packageinstaller/role/ui/DefaultAppListFragment.java @@ -158,9 +158,10 @@ public class DefaultAppListFragment extends SettingsFragment RoleItem roleItem = roleItems.get(i); Role role = roleItem.getRole(); - Preference preference = oldPreferences.get(role.getName()); + AppIconSettingsButtonPreference preference = + (AppIconSettingsButtonPreference) oldPreferences.get(role.getName()); if (preference == null) { - preference = new AppIconPreference(context); + preference = new AppIconSettingsButtonPreference(context); preference.setKey(role.getName()); preference.setIconSpaceReserved(true); preference.setTitle(role.getShortLabelResource()); @@ -178,6 +179,7 @@ public class DefaultAppListFragment extends SettingsFragment preference.setIcon(Utils.getBadgedIcon(context, holderApplicationInfo)); preference.setSummary(Utils.getAppLabel(holderApplicationInfo, context)); } + role.preparePreferenceAsUser(preference, user, context); preferenceGroup.addPreference(preference); } diff --git a/src/com/android/packageinstaller/role/ui/FooterPreference.java b/src/com/android/packageinstaller/role/ui/FooterPreference.java index 4c8a84496..cca4d347e 100644 --- a/src/com/android/packageinstaller/role/ui/FooterPreference.java +++ b/src/com/android/packageinstaller/role/ui/FooterPreference.java @@ -19,7 +19,7 @@ package com.android.packageinstaller.role.ui; import android.content.Context; import android.util.AttributeSet; import android.view.Gravity; -import android.view.ViewGroup; +import android.view.View; import android.widget.LinearLayout; import androidx.annotation.AttrRes; @@ -76,14 +76,14 @@ public class FooterPreference extends Preference { holder.setDividerAllowedAbove(true); - ViewGroup iconLayout = (ViewGroup) holder.findViewById(R.id.icon_frame); - LinearLayout.LayoutParams iconLayoutParams = (LinearLayout.LayoutParams) - iconLayout.getLayoutParams(); - iconLayoutParams.gravity = Gravity.TOP; - iconLayout.setLayoutParams(iconLayoutParams); - int iconLayoutPaddingVertical = UiUtils.dpToPxOffset(ICON_LAYOUT_PADDING_VERTICAL_DP, - iconLayout.getContext()); - iconLayout.setPaddingRelative(iconLayout.getPaddingStart(), iconLayoutPaddingVertical, - iconLayout.getPaddingEnd(), iconLayoutPaddingVertical); + View iconFrame = holder.findViewById(R.id.icon_frame); + LinearLayout.LayoutParams iconFrameLayoutParams = (LinearLayout.LayoutParams) + iconFrame.getLayoutParams(); + iconFrameLayoutParams.gravity = Gravity.TOP; + iconFrame.setLayoutParams(iconFrameLayoutParams); + int iconFramePaddingVertical = UiUtils.dpToPxOffset(ICON_LAYOUT_PADDING_VERTICAL_DP, + iconFrame.getContext()); + iconFrame.setPaddingRelative(iconFrame.getPaddingStart(), iconFramePaddingVertical, + iconFrame.getPaddingEnd(), iconFramePaddingVertical); } } diff --git a/src/com/android/packageinstaller/role/ui/RadioButtonPreference.java b/src/com/android/packageinstaller/role/ui/RadioButtonPreference.java index 95d091d8d..8f75c615a 100644 --- a/src/com/android/packageinstaller/role/ui/RadioButtonPreference.java +++ b/src/com/android/packageinstaller/role/ui/RadioButtonPreference.java @@ -18,6 +18,7 @@ package com.android.packageinstaller.role.ui; import android.content.Context; import android.util.AttributeSet; +import android.view.View; import android.view.ViewGroup; import android.widget.CompoundButton; import android.widget.RadioButton; @@ -47,6 +48,8 @@ public class RadioButtonPreference extends TwoStatePreference { } public RadioButtonPreference(@NonNull Context context, @Nullable AttributeSet attrs) { + // TwoStatePreference(Context, AttributeSet) breaks the default style attribute in + // Preference(Context, AttributeSet), so we need to add it back here. this(context, attrs, TypedArrayUtils.getAttr(context, R.attr.preferenceStyle, android.R.attr.preferenceStyle)); } @@ -60,22 +63,22 @@ public class RadioButtonPreference extends TwoStatePreference { @AttrRes int defStyleAttr, @StyleRes int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); - setWidgetLayoutResource(R.layout.preference_widget_radio_button); + setWidgetLayoutResource(R.layout.radio_button_preference_widget); } @Override public void onBindViewHolder(@NonNull PreferenceViewHolder holder) { super.onBindViewHolder(holder); - ViewGroup viewGroup = (ViewGroup) holder.itemView; - ViewGroup widgetFrame = (ViewGroup) holder.findViewById(android.R.id.widget_frame); - if (viewGroup.indexOfChild(widgetFrame) != 0) { + ViewGroup itemView = (ViewGroup) holder.itemView; + View widgetFrame = holder.findViewById(android.R.id.widget_frame); + if (itemView.indexOfChild(widgetFrame) != 0) { widgetFrame.setPaddingRelative(widgetFrame.getPaddingEnd(), widgetFrame.getPaddingTop(), widgetFrame.getPaddingStart(), widgetFrame.getPaddingBottom()); - viewGroup.removeView(widgetFrame); - viewGroup.addView(widgetFrame, 0); - viewGroup.setPaddingRelative(0, viewGroup.getPaddingTop(), viewGroup.getPaddingEnd(), - viewGroup.getPaddingBottom()); + itemView.removeView(widgetFrame); + itemView.addView(widgetFrame, 0); + itemView.setPaddingRelative(0, itemView.getPaddingTop(), itemView.getPaddingEnd(), + itemView.getPaddingBottom()); } RadioButton radioButton = (RadioButton) holder.findViewById(R.id.radio_button); diff --git a/src/com/android/packageinstaller/role/ui/SettingsButtonPreference.java b/src/com/android/packageinstaller/role/ui/SettingsButtonPreference.java new file mode 100644 index 000000000..e63508375 --- /dev/null +++ b/src/com/android/packageinstaller/role/ui/SettingsButtonPreference.java @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2019 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.packageinstaller.role.ui; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.View; + +import androidx.annotation.AttrRes; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.StyleRes; +import androidx.preference.Preference; +import androidx.preference.PreferenceViewHolder; + +import com.android.permissioncontroller.R; + +/** + * {@link Preference} with a settings button. + * + * @see com.android.settings.widget.GearPreference + */ +public class SettingsButtonPreference extends TwoTargetPreference { + + @Nullable + private OnSettingsButtonClickListener mOnSettingsButtonClickListener; + + public SettingsButtonPreference(@NonNull Context context, @Nullable AttributeSet attrs, + @AttrRes int defStyleAttr, @StyleRes int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + + init(); + } + + public SettingsButtonPreference(@NonNull Context context, @Nullable AttributeSet attrs, + @AttrRes int defStyleAttr) { + super(context, attrs, defStyleAttr); + + init(); + } + + public SettingsButtonPreference(@NonNull Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + + init(); + } + + public SettingsButtonPreference(@NonNull Context context) { + super(context); + + init(); + } + + private void init() { + setWidgetLayoutResource(R.layout.settings_button_preference_widget); + } + + /** + * Set the listener for settings button click. + * + * @param listener the listener + */ + public void setOnSettingsButtonClickListener(@Nullable OnSettingsButtonClickListener listener) { + mOnSettingsButtonClickListener = listener; + notifyChanged(); + } + + @Override + public void onBindViewHolder(@NonNull PreferenceViewHolder holder) { + super.onBindViewHolder(holder); + + View widgetFrame = holder.findViewById(android.R.id.widget_frame); + widgetFrame.setPadding(0, 0, 0, 0); + View settingsButton = holder.findViewById(R.id.settings_button); + if (mOnSettingsButtonClickListener != null) { + widgetFrame.setVisibility(View.VISIBLE); + settingsButton.setOnClickListener(view -> + mOnSettingsButtonClickListener.onSettingsButtonClick(this)); + } else { + widgetFrame.setVisibility(View.GONE); + settingsButton.setOnClickListener(null); + } + // Make the settings button enabled even if the preference itself is disabled. + settingsButton.setEnabled(true); + } + + /** + * Listener for settings button click. + */ + public interface OnSettingsButtonClickListener { + + /** + * Callback when settings button is clicked. + * + * @param preference the {@link SettingsButtonPreference} that was clicked + */ + void onSettingsButtonClick(@NonNull SettingsButtonPreference preference); + } +} diff --git a/src/com/android/packageinstaller/role/ui/SpecialAppAccessFragment.java b/src/com/android/packageinstaller/role/ui/SpecialAppAccessFragment.java index c7461e6a6..0fb0e37e6 100644 --- a/src/com/android/packageinstaller/role/ui/SpecialAppAccessFragment.java +++ b/src/com/android/packageinstaller/role/ui/SpecialAppAccessFragment.java @@ -149,6 +149,9 @@ public class SpecialAppAccessFragment extends SettingsFragment } preference.setChecked(isHolderPackage); + UserHandle user = UserHandle.getUserHandleForUid(qualifyingApplicationInfo.uid); + mRole.prepareApplicationPreferenceAsUser(preference, qualifyingApplicationInfo, user, + context); preferenceScreen.addPreference(preference); } diff --git a/src/com/android/packageinstaller/role/ui/SpecialAppAccessListFragment.java b/src/com/android/packageinstaller/role/ui/SpecialAppAccessListFragment.java index 11ecd766a..518e882c9 100644 --- a/src/com/android/packageinstaller/role/ui/SpecialAppAccessListFragment.java +++ b/src/com/android/packageinstaller/role/ui/SpecialAppAccessListFragment.java @@ -102,9 +102,10 @@ public class SpecialAppAccessListFragment extends SettingsFragment RoleItem roleItem = roleItems.get(i); Role role = roleItem.getRole(); - Preference preference = oldPreferences.get(role.getName()); + AppIconSettingsButtonPreference preference = + (AppIconSettingsButtonPreference) oldPreferences.get(role.getName()); if (preference == null) { - preference = new AppIconPreference(context); + preference = new AppIconSettingsButtonPreference(context); preference.setKey(role.getName()); preference.setIconSpaceReserved(true); preference.setTitle(role.getShortLabelResource()); @@ -112,6 +113,8 @@ public class SpecialAppAccessListFragment extends SettingsFragment preference.setOnPreferenceClickListener(this); } + role.preparePreferenceAsUser(preference, Process.myUserHandle(), context); + preferenceScreen.addPreference(preference); } diff --git a/src/com/android/packageinstaller/role/ui/TwoTargetPreference.java b/src/com/android/packageinstaller/role/ui/TwoTargetPreference.java new file mode 100644 index 000000000..0d49bb4a3 --- /dev/null +++ b/src/com/android/packageinstaller/role/ui/TwoTargetPreference.java @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2019 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.packageinstaller.role.ui; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.AttrRes; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.StyleRes; +import androidx.preference.Preference; +import androidx.preference.PreferenceViewHolder; + +import com.android.permissioncontroller.R; + +/** + * {@link Preference} with the widget layout as a separate target. + * + * @see com.android.settingslib.TwoTargetPreference + */ +public class TwoTargetPreference extends Preference { + + public TwoTargetPreference(@NonNull Context context, @Nullable AttributeSet attrs, + @AttrRes int defStyleAttr, @StyleRes int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + + init(); + } + + public TwoTargetPreference(@NonNull Context context, @Nullable AttributeSet attrs, + @AttrRes int defStyleAttr) { + super(context, attrs, defStyleAttr); + + init(); + } + + public TwoTargetPreference(@NonNull Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + + init(); + } + + public TwoTargetPreference(@NonNull Context context) { + super(context); + + init(); + } + + private void init() { + setLayoutResource(R.layout.two_target_preference); + } + + @Override + public void onBindViewHolder(@NonNull PreferenceViewHolder holder) { + super.onBindViewHolder(holder); + + View widgetFrame = holder.findViewById(android.R.id.widget_frame); + ViewGroup widgetFrameParent = (ViewGroup) widgetFrame.getParent(); + ViewGroup itemView = (ViewGroup) holder.itemView; + if (widgetFrameParent != itemView) { + widgetFrameParent.removeView(widgetFrame); + itemView.addView(widgetFrame); + } + } +} -- GitLab From 65a62d4e1306eb80550c67eeca1d2a8cc791a34f Mon Sep 17 00:00:00 2001 From: Jeff Hamilton Date: Fri, 29 Mar 2019 13:54:59 -0400 Subject: [PATCH 514/701] Set the version code to 0200000000 Bug: 129093117 Change-Id: I12ef0fea317cbe7567392a66c33b81f1fe59d850 --- AndroidManifest.xml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 3ea08f002..409458847 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1,8 +1,12 @@ - + -- GitLab From 96d135a101714441407d1254e54e6df6435c355f Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Fri, 29 Mar 2019 12:50:01 -0700 Subject: [PATCH 515/701] Add string for permissions without usage data. Bug: 129536503 Test: Compile Change-Id: I4a7e4e60911e95c744bbc3f668c1517d8b0c8552 --- res/values/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/res/values/strings.xml b/res/values/strings.xml index b58c0a60f..0fbb855f5 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -418,6 +418,9 @@ %1$s has not accessed your %2$s + + Last access data is currently not available for this permission + See all %1$s permissions -- GitLab From eb69a36674bb2ce4354e77d1882a9f85cf9bc784 Mon Sep 17 00:00:00 2001 From: Evan Severson Date: Thu, 28 Mar 2019 10:38:53 -0700 Subject: [PATCH 516/701] Add resources from BarChartPreference to overlayable Test: Build and verify overlayable Bug: 120435328 Bug: 126261357 Change-Id: I5100b91adaebf5570a5305886c52163af8795738 --- res/values/overlayable.xml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/res/values/overlayable.xml b/res/values/overlayable.xml index 2dc487cf0..3e675802a 100644 --- a/res/values/overlayable.xml +++ b/res/values/overlayable.xml @@ -111,6 +111,27 @@ + + + + + + + + + + + + + + + + + + + + + -- GitLab From a4249e5490233211a98f3a1aff148a445819161b Mon Sep 17 00:00:00 2001 From: Evan Severson Date: Thu, 28 Mar 2019 12:47:05 -0700 Subject: [PATCH 517/701] Make AppPreference icon size themeable Test: Build and test overlay Change-Id: I6676125d654fed45ba78232d51df7e6edd20c8f8 --- res/values/overlayable.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/res/values/overlayable.xml b/res/values/overlayable.xml index 3e675802a..e18f6fc5b 100644 --- a/res/values/overlayable.xml +++ b/res/values/overlayable.xml @@ -132,6 +132,11 @@ + + + + + -- GitLab From 95bb05b07f19afa244e6893df2028701b7506270 Mon Sep 17 00:00:00 2001 From: Evan Severson Date: Fri, 29 Mar 2019 12:59:22 -0700 Subject: [PATCH 518/701] Create more styles to become overlayable Bug: 120435328 Bug: 126261357 Test: Build and check appearance Change-Id: I302dc47a4bd773014fad88e78541649932b029d6 --- res/layout/header.xml | 29 +------ res/layout/header_large.xml | 2 +- res/layout/image_view.xml | 8 +- res/layout/loading_container.xml | 4 +- res/layout/permissions_frame.xml | 6 +- res/layout/preference_usage.xml | 46 ++-------- res/values/overlayable.xml | 30 +++++++ res/values/styles.xml | 143 ++++++++++++++++++++++++++++++- 8 files changed, 188 insertions(+), 80 deletions(-) diff --git a/res/layout/header.xml b/res/layout/header.xml index 20687d7b5..e52577d86 100644 --- a/res/layout/header.xml +++ b/res/layout/header.xml @@ -15,40 +15,19 @@ --> + style="@style/Header"> + style="@style/HeaderIcon" /> + style="@style/HeaderName" /> + style="@style/HeaderInfo" /> diff --git a/res/layout/header_large.xml b/res/layout/header_large.xml index 222fa7373..55980569f 100644 --- a/res/layout/header_large.xml +++ b/res/layout/header_large.xml @@ -23,7 +23,7 @@ + style="@style/LargeHeaderLink"/> diff --git a/res/layout/image_view.xml b/res/layout/image_view.xml index 3cd19e67e..3b93b6ee4 100644 --- a/res/layout/image_view.xml +++ b/res/layout/image_view.xml @@ -17,14 +17,10 @@ + style="@style/ImageView"> + style="@style/ImageViewIcon" /> diff --git a/res/layout/loading_container.xml b/res/layout/loading_container.xml index 5a165deee..de6c8011e 100644 --- a/res/layout/loading_container.xml +++ b/res/layout/loading_container.xml @@ -28,9 +28,7 @@ + style="@style/LoadingContainerTextView"/> diff --git a/res/layout/permissions_frame.xml b/res/layout/permissions_frame.xml index 4f71becba..70a89752c 100644 --- a/res/layout/permissions_frame.xml +++ b/res/layout/permissions_frame.xml @@ -39,11 +39,7 @@ - + style="@style/PermissionsFrameNoPermissionsText" /> diff --git a/res/layout/preference_usage.xml b/res/layout/preference_usage.xml index f606aa79d..0d69c2503 100644 --- a/res/layout/preference_usage.xml +++ b/res/layout/preference_usage.xml @@ -18,63 +18,35 @@ + style="@style/PreferenceUsage"> @@ -82,11 +54,7 @@ diff --git a/res/values/overlayable.xml b/res/values/overlayable.xml index e18f6fc5b..5f0193fd2 100644 --- a/res/values/overlayable.xml +++ b/res/values/overlayable.xml @@ -58,11 +58,22 @@ + + + + + + + + + + + @@ -91,6 +102,25 @@ + + + + + + + + + + + + + + + + + + + diff --git a/res/values/styles.xml b/res/values/styles.xml index bb560b2a4..743dcb0ef 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -178,6 +178,57 @@ + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- GitLab From 8b292c4c2b397f698f6e61cfe05df7e3699762ea Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Tue, 2 Apr 2019 09:24:50 -0700 Subject: [PATCH 530/701] Properly align title and summary text in Permissions Hub. Use the chain property of ConstraintLayout to ensure these two are centered vertically and packed together. Fixes: 129697624 Test: View dashboard with layout bounds and see centered text. Test: Increase font size and see centered text. Change-Id: I5a31e8cff5025f69ab57339afa5b1daa1f639df8 --- res/layout/preference_usage.xml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/res/layout/preference_usage.xml b/res/layout/preference_usage.xml index 0d69c2503..154d94cc6 100644 --- a/res/layout/preference_usage.xml +++ b/res/layout/preference_usage.xml @@ -36,7 +36,10 @@ + app:layout_constraintStart_toEndOf="@+id/title_widget_frame" + app:layout_constraintBottom_toTopOf="@android:id/summary" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintVertical_chainStyle="packed"/> + app:layout_constraintEnd_toStartOf="@android:id/widget_frame" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintVertical_chainStyle="packed"/> Date: Tue, 2 Apr 2019 10:04:22 -0700 Subject: [PATCH 531/701] Add margin above the empty permissions text header. Before it was right at the very top, which looked awkward. Test: Verified that the text spacing looks reasonable in PermissionUsageFragment. Test: Couldn't get it to appear on any other screen. Change-Id: I70acc46cef75816e421a148c0259ce57c21aca62 --- res/values/styles.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/res/values/styles.xml b/res/values/styles.xml index 743dcb0ef..1970dd53e 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -185,6 +185,7 @@ match_parent center ?android:attr/textAppearanceLarge + 32dp -- GitLab From 1f337b7939c947956c0d945cb2158e6bc728551e Mon Sep 17 00:00:00 2001 From: Evan Severson Date: Tue, 2 Apr 2019 10:03:39 -0700 Subject: [PATCH 532/701] Increase character limits on tri-state strings We want tri-state strings to be consistent in all places Bug: 129708972 Test: Build Change-Id: I27579d8ea4d81364c63f3fd47103c2df1004b7a7 --- res/values/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index b9328476c..d8b3507f2 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -189,13 +189,13 @@ @string/permission_access_never - + Allow all the time - + Allow only while using the app - + Deny -- GitLab From 61f1091bf9c00426a7f52a807284a70bd7f02454 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Tue, 2 Apr 2019 11:05:10 -0700 Subject: [PATCH 533/701] Properly invalidate the show/hide system apps menu. The old code only invalidated the options menu when it sees system apps for the first time. Now that we can change the definition of what is a system app, we should also invalidate the menu when there are no system apps when there used to be some. Fixes: 129477843 Test: Open dashboard, Advanced settings, toggle global/per-app switch, go back, refresh, see correct menu items. Change-Id: Ic20e040b57d51d94fdd3ec7e1e2f3ed50cee9668 --- .../ui/handheld/PermissionUsageFragment.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java index b4e8da4ac..a94da8c51 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java @@ -376,7 +376,7 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements } screen.removeAll(); - mHasSystemApps = false; + boolean seenSystemApp = false; final TimeFilterItem timeFilterItem = mFilterTimes.get(mFilterTimeIndex); long curTime = System.currentTimeMillis(); @@ -410,12 +410,7 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements } final boolean isSystemApp = !Utils.isGroupOrBgGroupUserSensitive( groupUsage.getGroup()); - if (!mHasSystemApps) { - if (isSystemApp) { - mHasSystemApps = true; - getActivity().invalidateOptionsMenu(); - } - } + seenSystemApp = seenSystemApp || isSystemApp; if (isSystemApp && !mShowSystem) { continue; } @@ -438,6 +433,11 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements } } + if (mHasSystemApps != seenSystemApp) { + mHasSystemApps = seenSystemApp; + getActivity().invalidateOptionsMenu(); + } + // Update header. if (mFilterGroup == null) { screen.addPreference(createBarChart(usages, timeFilterItem, context)); -- GitLab From a379986364be8f735d39a9c0c5dfc9a30554a339 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Tue, 2 Apr 2019 15:07:53 -0700 Subject: [PATCH 534/701] Reload AppPermissionFragment when it is resumed. This ensures that it picks up permission changes that happened when it was in the background. Fixes: 112642354 Test: Open fragment, disable permission, open the app, enable it, switch back to the fragment, see the radio button change. Test: Do the same but use adb to allow/revoke. Change-Id: I314559244cd20511a63014e4144bc85d4e23567c --- .../permission/ui/handheld/AppPermissionFragment.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java index b8cf63625..bbd0512b0 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java @@ -238,8 +238,6 @@ public class AppPermissionFragment extends SettingsWithLargeHeader { root.requireViewById(R.id.footer_all).setVisibility(View.GONE); } - updateButtons(); - return root; } @@ -293,6 +291,10 @@ public class AppPermissionFragment extends SettingsWithLargeHeader { ab.setElevation(0); } ActionBarShadowController.attachToView(activity, getLifecycle(), mNestedScrollView); + + // Re-create the permission group in case permissions have changed and update the UI. + createAppPermissionGroup(); + updateButtons(); } @Override -- GitLab From 41fb097160c34d21195773c2598a7a026b743e74 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Tue, 2 Apr 2019 15:55:46 -0700 Subject: [PATCH 535/701] Add function to control for which permissions to show usages. Add a function to control whether or not to show permission usages for each permission group. If we do not want to show them, we do not return the usages or show them in the UI. We also show a special string explaining it in AppPermissionFragment and PermissionAppsFragment. Note that we currently show usages for all groups, so this is currently a no-op. Fixes: 129536503 Test: Temporarily disable a permission's usages and inspect screens. Change-Id: Ic3482c1cee5d6aac5802be7d761974326f121624 --- .../permission/model/PermissionUsages.java | 3 ++ .../ui/handheld/AppPermissionFragment.java | 31 +++++++++++-------- .../ui/handheld/AppPermissionsFragment.java | 3 +- .../ui/handheld/PermissionAppsFragment.java | 12 +++++++ .../permission/utils/Utils.java | 11 +++++++ 5 files changed, 46 insertions(+), 14 deletions(-) diff --git a/src/com/android/packageinstaller/permission/model/PermissionUsages.java b/src/com/android/packageinstaller/permission/model/PermissionUsages.java index 09026eb98..0172635f7 100644 --- a/src/com/android/packageinstaller/permission/model/PermissionUsages.java +++ b/src/com/android/packageinstaller/permission/model/PermissionUsages.java @@ -217,6 +217,9 @@ public final class PermissionUsages implements LoaderCallbacks Date: Wed, 3 Apr 2019 09:40:32 -0700 Subject: [PATCH 536/701] Tweak the accessibility usage dialog's style. Bug: 129787770 Test: View dialog with one and two entries. Change-Id: I6bd2202f3126d322fa8c447619125d1479b067dc --- res/layout/accessibility_service_dialog.xml | 17 ++++++++--------- .../accessibility_service_dialog_item.xml | 3 +-- res/values/dimens.xml | 1 - 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/res/layout/accessibility_service_dialog.xml b/res/layout/accessibility_service_dialog.xml index 39f8807b0..38ce2695f 100644 --- a/res/layout/accessibility_service_dialog.xml +++ b/res/layout/accessibility_service_dialog.xml @@ -29,7 +29,7 @@ + android:layout_marginTop="18dp" /> + android:layout_marginTop="24dp" + android:layout_marginBottom="24dp" /> diff --git a/res/layout/accessibility_service_dialog_item.xml b/res/layout/accessibility_service_dialog_item.xml index c36ad86c8..b77d06f8b 100644 --- a/res/layout/accessibility_service_dialog_item.xml +++ b/res/layout/accessibility_service_dialog_item.xml @@ -42,8 +42,7 @@ android:layout_weight="1" android:layout_marginStart="@dimen/accessibility_service_dialog_text_padding" android:orientation="vertical" - android:paddingTop="16dp" - android:paddingBottom="16dp" > + android:paddingTop="18dp" > 16dp 24dp - 18dp 32dp 16dp -- GitLab From 8bfc9d47eb54a7529f23472a9720487251b26f71 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Wed, 3 Apr 2019 11:26:26 -0700 Subject: [PATCH 537/701] Fix PreferenceCategory style. We were using a PreferenceCategory defined in PermissionController, which overrode the global one. By removing it, we can apply themes to it to look more like Settings. Fixes: 128439459 Test: View permission screens. Change-Id: I8dfb518f6dc3cc6e77cc64005f0a6a0786b08168 --- res/layout/preference_category_material.xml | 35 --------------------- res/values/styles.xml | 8 ++--- res/values/themes.xml | 8 +++++ 3 files changed, 12 insertions(+), 39 deletions(-) delete mode 100644 res/layout/preference_category_material.xml diff --git a/res/layout/preference_category_material.xml b/res/layout/preference_category_material.xml deleted file mode 100644 index f62260bc1..000000000 --- a/res/layout/preference_category_material.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - diff --git a/res/values/styles.xml b/res/values/styles.xml index 9365ddcc5..335a6cb8f 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -269,13 +269,13 @@ ?android:attr/selectableItemBackground - + - -- GitLab From 0f87fe34a1a9bd8f13550b65b15e9fe8bbfca196 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Wed, 3 Apr 2019 16:25:15 -0700 Subject: [PATCH 542/701] Finish activities if Permissions Hub is disabled. Fixes: 129942065 Test: Open screens with Permissions Hub enabled and disabled. Change-Id: I8c0433650b6b43aa55bd17d31a640b60535c5a03 (cherry picked from commit 02f0fba945d2032ce3ea4b8c256ef8b8f6904225) --- .../permission/ui/ReviewAccessibilityServicesActivity.java | 1 + .../permission/ui/handheld/ReviewOngoingUsageFragment.java | 1 + 2 files changed, 2 insertions(+) diff --git a/src/com/android/packageinstaller/permission/ui/ReviewAccessibilityServicesActivity.java b/src/com/android/packageinstaller/permission/ui/ReviewAccessibilityServicesActivity.java index 7be781b3b..20db89e10 100644 --- a/src/com/android/packageinstaller/permission/ui/ReviewAccessibilityServicesActivity.java +++ b/src/com/android/packageinstaller/permission/ui/ReviewAccessibilityServicesActivity.java @@ -53,6 +53,7 @@ public final class ReviewAccessibilityServicesActivity extends FragmentActivity super.onCreate(savedInstanceState); if (!Utils.isPermissionsHubEnabled()) { + finish(); return; } diff --git a/src/com/android/packageinstaller/permission/ui/handheld/ReviewOngoingUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/ReviewOngoingUsageFragment.java index 10651487e..ad3ad89ac 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/ReviewOngoingUsageFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/ReviewOngoingUsageFragment.java @@ -77,6 +77,7 @@ public final class ReviewOngoingUsageFragment extends PreferenceFragmentCompat { super.onCreate(savedInstanceState); if (!Utils.isPermissionsHubEnabled()) { + getActivity().finish(); return; } -- GitLab From eac180779f5a2c30ca1ad9c21d0c7ee76bc676c7 Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Thu, 4 Apr 2019 10:16:43 -0700 Subject: [PATCH 543/701] Remove GrandfatheredModernStorageGroupWarningDialog This dialog is not needed anymore in Storage Permission Model 3. Test: Built Bug: 129716569 Change-Id: I57c094a9cab5ea4dd3d6b64dd7d2ac3f25789f02 --- res/drawable/ic_warning.xml | 25 ---------- res/layout/dialog_header.xml | 27 ---------- res/values/overlayable.xml | 7 --- res/values/strings.xml | 10 ---- res/values/styles.xml | 28 ----------- .../ui/handheld/AppPermissionFragment.java | 49 ------------------- 6 files changed, 146 deletions(-) delete mode 100644 res/drawable/ic_warning.xml delete mode 100644 res/layout/dialog_header.xml diff --git a/res/drawable/ic_warning.xml b/res/drawable/ic_warning.xml deleted file mode 100644 index e09331c29..000000000 --- a/res/drawable/ic_warning.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - \ No newline at end of file diff --git a/res/layout/dialog_header.xml b/res/layout/dialog_header.xml deleted file mode 100644 index 0123a05e8..000000000 --- a/res/layout/dialog_header.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - diff --git a/res/values/overlayable.xml b/res/values/overlayable.xml index 237376346..f18db51cc 100644 --- a/res/values/overlayable.xml +++ b/res/values/overlayable.xml @@ -121,13 +121,6 @@ - - - - - - - diff --git a/res/values/strings.xml b/res/values/strings.xml index d8b3507f2..5de331190 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -797,16 +797,6 @@ Allow %4$s to upload a bug repo Deny - - Permission can\u2019t be denied. Uninstall %1$s. - - - %1$s has legacy storage permission to keep your previous data accessible, and the app can stop working when this permission is denied.\n\nTo continue using the app, uninstall it and then reinstall it. Your data in this app may be lost. - - - Got it - Advanced settings diff --git a/res/values/styles.xml b/res/values/styles.xml index a30380f7b..ed3e93f2e 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -518,34 +518,6 @@ - - - - - - - - - - + + + + + + + + + -- GitLab From 6059c85162684f92dc78aea2a868bd71cd0318f6 Mon Sep 17 00:00:00 2001 From: Michael Groover Date: Tue, 9 Apr 2019 16:56:16 -0700 Subject: [PATCH 560/701] Grant READ_DEVICE_IDENTIFIERS appop to SMS role holder Bug: 124236412 Test: cts-tradefed run cts-dev -m CtsAppSecurityHostTestCases -t \ android.appsecurity.cts.DeviceIdentifierTest#testDeviceIdentifierAccessWithAppOpGranted Test: Manually verified app holding SMS role could access device identifiers. Change-Id: Id8ebfb39d40830dcf8d2d138f378b82e1bae40e6 --- res/xml/roles.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/res/xml/roles.xml b/res/xml/roles.xml index 82cc9823f..617fc4d8d 100644 --- a/res/xml/roles.xml +++ b/res/xml/roles.xml @@ -271,6 +271,7 @@ --> + -- GitLab From 149ef4b11600d683cd28ff483697885eaf3a82fa Mon Sep 17 00:00:00 2001 From: Joe Onorato Date: Thu, 4 Apr 2019 11:23:44 -0700 Subject: [PATCH 561/701] Fix typo in incident confirmation string. Test: treehugger Bug: 129896626 Change-Id: If50bc07d96eb2582b070ee19c0b47d3bcfdeec76 --- res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 24717877e..d8d30c9b0 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -770,7 +770,7 @@ Allow %4$s to upload a bug repo - "There was an error processing the bug report for %1$s. So sharing the detailed debugging data data has been denied. Sorry for the interruption." + "There was an error processing the bug report for %1$s. So sharing the detailed debugging data has been denied. Sorry for the interruption." Allow -- GitLab From a7f909f4e8c161cedf1031badcc6fc9b8be307a8 Mon Sep 17 00:00:00 2001 From: Joe Onorato Date: Wed, 10 Apr 2019 00:55:01 -0700 Subject: [PATCH 562/701] Turn off debugging code now that things are working. Test: treehugger Bug: 123543706 Change-Id: I7d7a8d8bd6e57ee674581c09e7702d0f7795fc8b --- .../android/packageinstaller/incident/ConfirmationActivity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/android/packageinstaller/incident/ConfirmationActivity.java b/src/com/android/packageinstaller/incident/ConfirmationActivity.java index 724c34ecb..639f66470 100644 --- a/src/com/android/packageinstaller/incident/ConfirmationActivity.java +++ b/src/com/android/packageinstaller/incident/ConfirmationActivity.java @@ -296,7 +296,7 @@ public class ConfirmationActivity extends Activity implements OnClickListener, O } // Test data - if (true) { + if (false) { drawables.add(new android.graphics.drawable.BitmapDrawable(res, new ByteArrayInputStream(new byte[] { // png image data -- GitLab From d76b792fb4c0928da2f8820b964635fefa0138fb Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Wed, 10 Apr 2019 20:13:20 +0800 Subject: [PATCH 563/701] Improve a11y of role UI. Call setChecked() for RadioButton so that it reports the correct checked state for a11y, and increse CheckBox touch target size. Bug: 128713569 Test: manual Change-Id: I4e24303d342be286af56ffe9026e493d35ba7319 --- res/values/styles.xml | 2 +- .../role/ui/CheckableLinearLayout.java | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/res/values/styles.xml b/res/values/styles.xml index 48504122d..852d3e33f 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -703,7 +703,7 @@ diff --git a/src/com/android/packageinstaller/role/ui/CheckableLinearLayout.java b/src/com/android/packageinstaller/role/ui/CheckableLinearLayout.java index 19e770d01..507bef783 100644 --- a/src/com/android/packageinstaller/role/ui/CheckableLinearLayout.java +++ b/src/com/android/packageinstaller/role/ui/CheckableLinearLayout.java @@ -18,6 +18,8 @@ package com.android.packageinstaller.role.ui; import android.content.Context; import android.util.AttributeSet; +import android.view.View; +import android.view.ViewGroup; import android.widget.Checkable; import android.widget.LinearLayout; @@ -71,6 +73,7 @@ public class CheckableLinearLayout extends LinearLayout implements Checkable { mChecked = checked; refreshDrawableState(); + updateChildrenChecked(); } @Override @@ -87,4 +90,23 @@ public class CheckableLinearLayout extends LinearLayout implements Checkable { } return state; } + + private void updateChildrenChecked() { + updateChildrenChecked(this, mChecked); + } + + // We call setChecked() on checkable children so that accessibility can get the correct state. + private static void updateChildrenChecked(@NonNull ViewGroup viewGroup, boolean checked) { + int count = viewGroup.getChildCount(); + for (int i = 0; i < count; i++) { + View child = viewGroup.getChildAt(i); + if (child.isDuplicateParentStateEnabled()) { + if (child instanceof Checkable) { + ((Checkable) child).setChecked(checked); + } else if (child instanceof ViewGroup) { + updateChildrenChecked((ViewGroup) child, checked); + } + } + } + } } -- GitLab From 66dc7dec9e7315e7bdf7a12b3966006835417e94 Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Wed, 10 Apr 2019 20:28:44 +0800 Subject: [PATCH 564/701] Fix RequestRoleItem themeability. Use the defined overlayable style. Bug: 129277411 Test: manual Change-Id: I6ed746c68d297337c69c5aa9e8414801ebd29549 --- res/layout/request_role_item.xml | 8 +------- res/layout/request_role_title.xml | 2 -- res/values/styles.xml | 13 ++++++++----- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/res/layout/request_role_item.xml b/res/layout/request_role_item.xml index 6b59a3f17..95c92e855 100644 --- a/res/layout/request_role_item.xml +++ b/res/layout/request_role_item.xml @@ -20,12 +20,7 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" - android:minHeight="?android:listPreferredItemHeight" - android:paddingStart="?android:listPreferredItemPaddingStart" - android:paddingEnd="?android:listPreferredItemPaddingEnd" - android:clipChildren="false" - android:gravity="center_vertical" - android:orientation="horizontal"> + style="@style/RequestRoleItem"> - diff --git a/res/layout/request_role_title.xml b/res/layout/request_role_title.xml index b97081206..48842f083 100644 --- a/res/layout/request_role_title.xml +++ b/res/layout/request_role_title.xml @@ -18,8 +18,6 @@ - - @@ -695,4 +689,113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- GitLab From ec2fcbdd4aba4c9f61753447711616192aa496e8 Mon Sep 17 00:00:00 2001 From: Evan Severson Date: Fri, 12 Apr 2019 11:14:10 -0700 Subject: [PATCH 572/701] Add string to differentiate storage permission requests Show a different request string for isolated storage Test: Build and check dialog for various permissions Fixes: 129945863 Change-Id: Ibc08e34b58005418aa613ffc6bb6a777729a1679 --- res/values/strings.xml | 4 ++++ .../android/packageinstaller/permission/utils/Utils.java | 7 ++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index d8d30c9b0..bd2135edb 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -798,4 +798,8 @@ Allow %4$s to upload a bug repo Show icon in status bar when microphone is used to activate voice assistant + + + Allow + <b>%1$s</b> to access photos and media on your device? diff --git a/src/com/android/packageinstaller/permission/utils/Utils.java b/src/com/android/packageinstaller/permission/utils/Utils.java index 9f5de77e9..4b994cc77 100644 --- a/src/com/android/packageinstaller/permission/utils/Utils.java +++ b/src/com/android/packageinstaller/permission/utils/Utils.java @@ -552,7 +552,12 @@ public final class Utils { */ public static CharSequence getRequestMessage(CharSequence appLabel, AppPermissionGroup group, Context context, @StringRes int requestRes) { - if (requestRes != 0) { + if (group.getName().equals(STORAGE) && !group.isNonIsolatedStorage()) { + return Html.fromHtml( + String.format(context.getResources().getConfiguration().getLocales().get(0), + context.getString(R.string.permgrouprequest_storage_isolated), + appLabel), 0); + } else if (requestRes != 0) { try { return Html.fromHtml(context.getPackageManager().getResourcesForApplication( group.getDeclaringPackage()).getString(requestRes, appLabel), 0); -- GitLab From f8fcb5490664508ca8cb8d188ea3600508509794 Mon Sep 17 00:00:00 2001 From: Evan Severson Date: Mon, 8 Apr 2019 15:46:22 -0700 Subject: [PATCH 573/701] Make title_summary_image_view themeable Test: Build and look at expandable preferences Fixes: 130433836 Change-Id: I98bc7a0076457e23bb4420e8b08f7956da4e3b6f --- res/layout/title_summary_image_view.xml | 5 +---- res/values/dimens.xml | 2 -- res/values/overlayable.xml | 4 ++++ res/values/styles.xml | 11 +++++++++++ 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/res/layout/title_summary_image_view.xml b/res/layout/title_summary_image_view.xml index eef4a21d6..2aa144072 100644 --- a/res/layout/title_summary_image_view.xml +++ b/res/layout/title_summary_image_view.xml @@ -22,9 +22,6 @@ + style="@style/TitleSummaryImageViewIcon" /> diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 4fc3fb70e..ecdf6dc6a 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -45,8 +45,6 @@ 8dp 24dp - 16dp - 150dp 200dp diff --git a/res/values/overlayable.xml b/res/values/overlayable.xml index 2110ba3b9..866437a7b 100644 --- a/res/values/overlayable.xml +++ b/res/values/overlayable.xml @@ -112,6 +112,10 @@ + + + + diff --git a/res/values/styles.xml b/res/values/styles.xml index fabcad82e..d7375959e 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -494,6 +494,17 @@ + + + + + + + + @@ -84,7 +83,6 @@ match_parent wrap_content vertical - @*android:drawable/list_divider_material middle @@ -95,7 +93,7 @@ diff --git a/res/values/themes.xml b/res/values/themes.xml index 3eb00b4e9..4dd6e326d 100644 --- a/res/values/themes.xml +++ b/res/values/themes.xml @@ -23,7 +23,7 @@ @style/TextAppearance.CategoryTitle + + + + + diff --git a/res/values/themes.xml b/res/values/themes.xml index 4dd6e326d..848cd78a3 100644 --- a/res/values/themes.xml +++ b/res/values/themes.xml @@ -22,6 +22,12 @@ @style/PreferenceThemeOverlay @style/TextAppearance.CategoryTitle + + + + + + + diff --git a/src/com/android/packageinstaller/role/ui/DefaultAppListActivity.java b/src/com/android/packageinstaller/role/ui/DefaultAppListActivity.java index 15de17864..e312d8d63 100644 --- a/src/com/android/packageinstaller/role/ui/DefaultAppListActivity.java +++ b/src/com/android/packageinstaller/role/ui/DefaultAppListActivity.java @@ -20,9 +20,13 @@ import android.os.Bundle; import android.view.WindowManager; import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; +import com.android.packageinstaller.DeviceUtils; +import com.android.packageinstaller.role.ui.auto.AutoDefaultAppListFragment; import com.android.packageinstaller.role.ui.handheld.HandheldDefaultAppListFragment; +import com.android.permissioncontroller.R; /** * Activity for the list of default apps. @@ -31,13 +35,23 @@ public class DefaultAppListActivity extends FragmentActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { + if (DeviceUtils.isAuto(this)) { + // Automotive relies on a different theme. Apply before calling super so that + // fragments are restored properly on configuration changes. + setTheme(R.style.CarSettings); + } super.onCreate(savedInstanceState); getWindow().addSystemFlags( WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS); if (savedInstanceState == null) { - HandheldDefaultAppListFragment fragment = HandheldDefaultAppListFragment.newInstance(); + Fragment fragment; + if (DeviceUtils.isAuto(this)) { + fragment = AutoDefaultAppListFragment.newInstance(); + } else { + fragment = HandheldDefaultAppListFragment.newInstance(); + } getSupportFragmentManager().beginTransaction() .add(android.R.id.content, fragment) .commit(); diff --git a/src/com/android/packageinstaller/role/ui/auto/AutoDefaultAppListFragment.java b/src/com/android/packageinstaller/role/ui/auto/AutoDefaultAppListFragment.java new file mode 100644 index 000000000..2d6fbacd1 --- /dev/null +++ b/src/com/android/packageinstaller/role/ui/auto/AutoDefaultAppListFragment.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2019 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.packageinstaller.role.ui.auto; + +import android.content.Context; +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.android.packageinstaller.role.ui.DefaultAppListChildFragment; +import com.android.packageinstaller.role.ui.TwoTargetPreference; +import com.android.permissioncontroller.R; + +/** Shows various roles for which a default app can be picked. */ +public class AutoDefaultAppListFragment extends DefaultAppFrameFragment implements + DefaultAppListChildFragment.Parent { + + /** Create a new instance of this fragment. */ + @NonNull + public static AutoDefaultAppListFragment newInstance() { + return new AutoDefaultAppListFragment(); + } + + @Override + public void onActivityCreated(@Nullable Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + if (savedInstanceState == null) { + DefaultAppListChildFragment fragment = DefaultAppListChildFragment.newInstance(); + getChildFragmentManager().beginTransaction() + .add(fragment, null) + .commit(); + } + + setHeaderLabel(getString(R.string.default_apps)); + } + + @NonNull + @Override + public TwoTargetPreference createPreference(@NonNull Context context) { + return new AutoSettingsPreference(context); + } + + @Override + public void onPreferenceScreenChanged() { + } +} diff --git a/src/com/android/packageinstaller/role/ui/auto/AutoSettingsPreference.java b/src/com/android/packageinstaller/role/ui/auto/AutoSettingsPreference.java new file mode 100644 index 000000000..56e16a63a --- /dev/null +++ b/src/com/android/packageinstaller/role/ui/auto/AutoSettingsPreference.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2019 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.packageinstaller.role.ui.auto; + +import android.content.Context; +import android.util.AttributeSet; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.android.packageinstaller.role.ui.TwoTargetPreference; + +/** + * Preference to show default app list. Extends {@link TwoTargetPreference} in order to make sure of + * shared logic between phone and auto settings UI. + */ +public class AutoSettingsPreference extends TwoTargetPreference { + + public AutoSettingsPreference(@NonNull Context context, + @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + } + + public AutoSettingsPreference(@NonNull Context context, @Nullable AttributeSet attrs, + int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + public AutoSettingsPreference(@NonNull Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + } + + public AutoSettingsPreference(@NonNull Context context) { + super(context); + } + + @Override + public void setOnSecondTargetClickListener(@Nullable OnSecondTargetClickListener listener) { + return; + } +} diff --git a/src/com/android/packageinstaller/role/ui/auto/DefaultAppFrameFragment.java b/src/com/android/packageinstaller/role/ui/auto/DefaultAppFrameFragment.java new file mode 100644 index 000000000..8733a8510 --- /dev/null +++ b/src/com/android/packageinstaller/role/ui/auto/DefaultAppFrameFragment.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2019 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.packageinstaller.role.ui.auto; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.preference.PreferenceFragmentCompat; + +import com.android.permissioncontroller.R; + +/** Base fragment to be used by car variants of the default app settings screens. */ +public class DefaultAppFrameFragment extends PreferenceFragmentCompat { + + private TextView mLabelView; + private CharSequence mLabel; + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + View rootView = super.onCreateView(inflater, container, savedInstanceState); + View backButton = rootView.findViewById(R.id.back_button); + backButton.setOnClickListener(v -> getActivity().onBackPressed()); + + mLabelView = rootView.findViewById(R.id.label); + updateHeaderLabel(); + + return rootView; + } + + /** Sets the header text of this fragment. */ + public void setHeaderLabel(CharSequence label) { + mLabel = label; + updateHeaderLabel(); + } + + /** Gets the header text of this fragment. */ + public CharSequence getHeaderLabel() { + return mLabel; + } + + @Override + public void onCreatePreferences(Bundle bundle, String s) { + // We'll manually add preferences later. + } + + private void updateHeaderLabel() { + if (mLabelView != null) { + mLabelView.setText(mLabel); + } + } +} -- GitLab From ead4dfd1292aafd2650ea74b4e8b652341a6453f Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Fri, 3 May 2019 09:36:32 -0700 Subject: [PATCH 616/701] Support multiple profiles in AllAppPermissionsFragment This required changing a number of callsites. In addition, I fixed SettingsWithLargeHeader's icon to be clickable, although it's only used in one place. And I disabled that place to be consistent with Settings' app info, which makes it non-clickable. Fixes: 131859961 Test: Open work app's AppPermissionsFragment, select "All Permissions", see work profile icon, click info button, see work profile icon. Test: Do the same for non-work app and see unbadged icon. Test: Grant permission through the dialog. Test: Click on AppPermissionsFragment's header for work/normal app when coming through AppPermissionFragment. It worked before I disabled it. Change-Id: I14e05b40e77b3949f5e5535070da9f1c524fef5a --- .../ui/GrantPermissionsActivity.java | 27 ++++++++++--------- .../ui/ManagePermissionsActivity.java | 10 +++---- .../auto/GrantPermissionsAutoViewHandler.java | 6 +++-- .../handheld/AllAppPermissionsFragment.java | 26 ++++++++++-------- .../ui/handheld/AppPermissionFragment.java | 5 ++-- .../ui/handheld/AppPermissionsFragment.java | 7 ++--- .../GrantPermissionsViewHandlerImpl.java | 9 ++++++- .../ui/handheld/PermissionAppsFragment.java | 4 +-- .../ui/handheld/PermissionPreference.java | 3 ++- .../ui/handheld/PermissionUsageFragment.java | 2 +- .../handheld/ReviewPermissionsFragment.java | 3 +++ .../ui/handheld/SettingsWithHeader.java | 20 +++++++------- .../ui/handheld/SettingsWithLargeHeader.java | 9 ++++++- 13 files changed, 80 insertions(+), 51 deletions(-) diff --git a/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java b/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java index 73b393233..73916c76e 100644 --- a/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java +++ b/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java @@ -45,6 +45,7 @@ import android.content.res.Resources; import android.graphics.drawable.Icon; import android.os.Build; import android.os.Bundle; +import android.os.UserHandle; import android.permission.PermissionManager; import android.text.Html; import android.text.Spanned; @@ -264,6 +265,18 @@ public class GrantPermissionsActivity extends Activity setTitle(R.string.permission_request_title); + PackageInfo callingPackageInfo = getCallingPackageInfo(); + + if (callingPackageInfo == null || callingPackageInfo.requestedPermissions == null + || callingPackageInfo.requestedPermissions.length <= 0) { + setResultAndFinish(); + return; + } + + mCallingUid = callingPackageInfo.applicationInfo.uid; + + UserHandle userHandle = UserHandle.getUserHandleForUid(mCallingUid); + if (DeviceUtils.isTelevision(this)) { mViewHandler = new com.android.packageinstaller.permission.ui.television .GrantPermissionsViewHandlerImpl(this, @@ -271,11 +284,11 @@ public class GrantPermissionsActivity extends Activity } else if (DeviceUtils.isWear(this)) { mViewHandler = new GrantPermissionsWatchViewHandler(this).setResultListener(this); } else if (DeviceUtils.isAuto(this)) { - mViewHandler = new GrantPermissionsAutoViewHandler(this, mCallingPackage) + mViewHandler = new GrantPermissionsAutoViewHandler(this, mCallingPackage, userHandle) .setResultListener(this); } else { mViewHandler = new com.android.packageinstaller.permission.ui.handheld - .GrantPermissionsViewHandlerImpl(this, mCallingPackage) + .GrantPermissionsViewHandlerImpl(this, mCallingPackage, userHandle) .setResultListener(this); } @@ -292,16 +305,6 @@ public class GrantPermissionsActivity extends Activity return; } - PackageInfo callingPackageInfo = getCallingPackageInfo(); - - if (callingPackageInfo == null || callingPackageInfo.requestedPermissions == null - || callingPackageInfo.requestedPermissions.length <= 0) { - setResultAndFinish(); - return; - } - - mCallingUid = callingPackageInfo.applicationInfo.uid; - // Don't allow legacy apps to request runtime permissions. if (callingPackageInfo.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { // Returning empty arrays means a cancellation. diff --git a/src/com/android/packageinstaller/permission/ui/ManagePermissionsActivity.java b/src/com/android/packageinstaller/permission/ui/ManagePermissionsActivity.java index 4de5b404d..b15127cf6 100644 --- a/src/com/android/packageinstaller/permission/ui/ManagePermissionsActivity.java +++ b/src/com/android/packageinstaller/permission/ui/ManagePermissionsActivity.java @@ -114,14 +114,14 @@ public final class ManagePermissionsActivity extends FragmentActivity { } else { final boolean allPermissions = getIntent().getBooleanExtra( EXTRA_ALL_PERMISSIONS, false); + UserHandle userHandle = getIntent().getParcelableExtra(Intent.EXTRA_USER); + if (userHandle == null) { + userHandle = UserHandle.of(UserHandle.myUserId()); + } if (allPermissions) { androidXFragment = com.android.packageinstaller.permission.ui.handheld - .AllAppPermissionsFragment.newInstance(packageName); + .AllAppPermissionsFragment.newInstance(packageName, userHandle); } else { - UserHandle userHandle = getIntent().getParcelableExtra(Intent.EXTRA_USER); - if (userHandle == null) { - userHandle = UserHandle.of(UserHandle.myUserId()); - } androidXFragment = com.android.packageinstaller.permission.ui.handheld .AppPermissionsFragment.newInstance(packageName, userHandle); } diff --git a/src/com/android/packageinstaller/permission/ui/auto/GrantPermissionsAutoViewHandler.java b/src/com/android/packageinstaller/permission/ui/auto/GrantPermissionsAutoViewHandler.java index 9e40d6643..2b7702e0f 100644 --- a/src/com/android/packageinstaller/permission/ui/auto/GrantPermissionsAutoViewHandler.java +++ b/src/com/android/packageinstaller/permission/ui/auto/GrantPermissionsAutoViewHandler.java @@ -17,6 +17,7 @@ package com.android.packageinstaller.permission.ui.auto; import android.app.Activity; +import android.os.UserHandle; import android.view.WindowManager; import com.android.packageinstaller.permission.ui.handheld.GrantPermissionsViewHandlerImpl; @@ -30,8 +31,9 @@ import com.android.packageinstaller.permission.ui.handheld.GrantPermissionsViewH * change the window params to allow the dialog's width to be larger. */ public class GrantPermissionsAutoViewHandler extends GrantPermissionsViewHandlerImpl { - public GrantPermissionsAutoViewHandler(Activity activity, String appPackageName) { - super(activity, appPackageName); + public GrantPermissionsAutoViewHandler(Activity activity, String appPackageName, + UserHandle userHandle) { + super(activity, appPackageName, userHandle); } /** diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AllAppPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AllAppPermissionsFragment.java index 373be21b1..ce75f4097 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AllAppPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AllAppPermissionsFragment.java @@ -31,12 +31,14 @@ import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Build; import android.os.Bundle; +import android.os.UserHandle; import android.provider.Settings; import android.text.TextUtils; import android.util.Log; import android.view.MenuItem; import android.widget.Switch; +import androidx.annotation.NonNull; import androidx.preference.Preference; import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceGroup; @@ -63,20 +65,20 @@ public final class AllAppPermissionsFragment extends SettingsWithHeader { private static final String KEY_OTHER = "other_perms"; - private static final String EXTRA_FILTER_GROUP = - "com.android.packageinstaller.extra.FILTER_GROUP"; - private List mGroups; - public static AllAppPermissionsFragment newInstance(String packageName) { - return newInstance(packageName, null); + public static AllAppPermissionsFragment newInstance(@NonNull String packageName, + @NonNull UserHandle userHandle) { + return newInstance(packageName, null, userHandle); } - public static AllAppPermissionsFragment newInstance(String packageName, String filterGroup) { + public static AllAppPermissionsFragment newInstance(@NonNull String packageName, + @NonNull String filterGroup, @NonNull UserHandle userHandle) { AllAppPermissionsFragment instance = new AllAppPermissionsFragment(); Bundle arguments = new Bundle(); arguments.putString(Intent.EXTRA_PACKAGE_NAME, packageName); - arguments.putString(EXTRA_FILTER_GROUP, filterGroup); + arguments.putString(Intent.EXTRA_PERMISSION_GROUP_NAME, filterGroup); + arguments.putParcelable(Intent.EXTRA_USER, userHandle); instance.setArguments(arguments); return instance; } @@ -88,7 +90,7 @@ public final class AllAppPermissionsFragment extends SettingsWithHeader { final ActionBar ab = getActivity().getActionBar(); if (ab != null) { // If we target a group make this look like app permissions. - if (getArguments().getString(EXTRA_FILTER_GROUP) == null) { + if (getArguments().getString(Intent.EXTRA_PERMISSION_GROUP_NAME) == null) { ab.setTitle(R.string.all_permissions); } else { ab.setTitle(R.string.app_permissions); @@ -121,12 +123,14 @@ public final class AllAppPermissionsFragment extends SettingsWithHeader { ArrayList prefs = new ArrayList<>(); // Used for sorting. prefs.add(otherGroup); String pkg = getArguments().getString(Intent.EXTRA_PACKAGE_NAME); - String filterGroup = getArguments().getString(EXTRA_FILTER_GROUP); + String filterGroup = getArguments().getString(Intent.EXTRA_PERMISSION_GROUP_NAME); + UserHandle userHandle = getArguments().getParcelable(Intent.EXTRA_USER); otherGroup.removeAll(); PackageManager pm = getContext().getPackageManager(); try { - PackageInfo info = pm.getPackageInfo(pkg, PackageManager.GET_PERMISSIONS); + PackageInfo info = getActivity().createPackageContextAsUser(pkg, 0, userHandle) + .getPackageManager().getPackageInfo(pkg, PackageManager.GET_PERMISSIONS); ApplicationInfo appInfo = info.applicationInfo; final Drawable icon = Utils.getBadgedIcon(getContext(), appInfo); @@ -137,7 +141,7 @@ public final class AllAppPermissionsFragment extends SettingsWithHeader { infoIntent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) .setData(Uri.fromParts("package", pkg, null)); } - setHeader(icon, label, infoIntent); + setHeader(icon, label, infoIntent, userHandle); if (info.requestedPermissions != null) { for (int i = 0; i < info.requestedPermissions.length; i++) { diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java index 2737002f9..b0d53945b 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java @@ -186,7 +186,7 @@ public class AppPermissionFragment extends SettingsWithLargeHeader { } String appLabel = Utils.getFullAppLabel(mGroup.getApp().applicationInfo, context); - setHeader(getAppIcon(), appLabel, null, false); + setHeader(getAppIcon(), appLabel, null, null, false); updateHeader(root.requireViewById(R.id.large_header)); ((TextView) root.requireViewById(R.id.permission_message)).setText( @@ -212,6 +212,7 @@ public class AppPermissionFragment extends SettingsWithLargeHeader { Intent intent = new Intent(Intent.ACTION_MANAGE_APP_PERMISSIONS); intent.putExtra(Intent.EXTRA_PACKAGE_NAME, mGroup.getApp().packageName); intent.putExtra(Intent.EXTRA_USER, user); + intent.putExtra(AppPermissionsFragment.EXTRA_HIDE_INFO_BUTTON, true); context.startActivity(intent); }); @@ -744,7 +745,7 @@ public class AppPermissionFragment extends SettingsWithLargeHeader { */ private void showAllPermissions(@NonNull String filterGroup) { Fragment frag = AllAppPermissionsFragment.newInstance(mGroup.getApp().packageName, - filterGroup); + filterGroup, UserHandle.getUserHandleForUid(mGroup.getApp().applicationInfo.uid)); getFragmentManager().beginTransaction() .replace(android.R.id.content, frag) .addToBackStack("AllPerms") diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java index 098c9d00c..0faf3a009 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java @@ -160,7 +160,7 @@ public final class AppPermissionsFragment extends SettingsWithLargeHeader { private void showAllPermissions(String filterGroup) { Fragment frag = AllAppPermissionsFragment.newInstance( getArguments().getString(Intent.EXTRA_PACKAGE_NAME), - filterGroup); + filterGroup, getArguments().getParcelable(Intent.EXTRA_USER)); getFragmentManager().beginTransaction() .replace(android.R.id.content, frag) .addToBackStack("AllPerms") @@ -177,7 +177,8 @@ public final class AppPermissionsFragment extends SettingsWithLargeHeader { } Drawable icon = Utils.getBadgedIcon(activity, appInfo); - fragment.setHeader(icon, Utils.getFullAppLabel(appInfo, activity), infoIntent, false); + fragment.setHeader(icon, Utils.getFullAppLabel(appInfo, activity), infoIntent, + UserHandle.getUserHandleForUid(appInfo.uid), false); ActionBar ab = activity.getActionBar(); if (ab != null) { @@ -330,7 +331,7 @@ public final class AppPermissionsFragment extends SettingsWithLargeHeader { public void onCreate(Bundle savedInstanceState) { mOuterFragment = (AppPermissionsFragment) getTargetFragment(); super.onCreate(savedInstanceState); - setHeader(mOuterFragment.mIcon, mOuterFragment.mLabel, null, false); + setHeader(mOuterFragment.mIcon, mOuterFragment.mLabel, null, null, false); setHasOptionsMenu(true); setPreferenceScreen(mOuterFragment.mExtraScreen); } diff --git a/src/com/android/packageinstaller/permission/ui/handheld/GrantPermissionsViewHandlerImpl.java b/src/com/android/packageinstaller/permission/ui/handheld/GrantPermissionsViewHandlerImpl.java index 03ca1eeef..d6eebefc9 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/GrantPermissionsViewHandlerImpl.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/GrantPermissionsViewHandlerImpl.java @@ -26,6 +26,7 @@ import android.app.Activity; import android.content.Intent; import android.graphics.drawable.Icon; import android.os.Bundle; +import android.os.UserHandle; import android.transition.ChangeBounds; import android.transition.TransitionManager; import android.view.LayoutInflater; @@ -39,6 +40,8 @@ import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; +import androidx.annotation.NonNull; + import com.android.packageinstaller.permission.ui.GrantPermissionsViewHandler; import com.android.packageinstaller.permission.ui.ManagePermissionsActivity; import com.android.permissioncontroller.R; @@ -60,6 +63,7 @@ public class GrantPermissionsViewHandlerImpl implements GrantPermissionsViewHand private final Activity mActivity; private final String mAppPackageName; + private final UserHandle mUserHandle; private ResultListener mResultListener; @@ -83,9 +87,11 @@ public class GrantPermissionsViewHandlerImpl implements GrantPermissionsViewHand private Button mDenyAndDontAskAgainButton; private ViewGroup mRootView; - public GrantPermissionsViewHandlerImpl(Activity activity, String appPackageName) { + public GrantPermissionsViewHandlerImpl(Activity activity, String appPackageName, + @NonNull UserHandle userHandle) { mActivity = activity; mAppPackageName = appPackageName; + mUserHandle = userHandle; } @Override @@ -287,6 +293,7 @@ public class GrantPermissionsViewHandlerImpl implements GrantPermissionsViewHand case R.id.permission_more_info_button: Intent intent = new Intent(Intent.ACTION_MANAGE_APP_PERMISSIONS); intent.putExtra(Intent.EXTRA_PACKAGE_NAME, mAppPackageName); + intent.putExtra(Intent.EXTRA_USER, mUserHandle); intent.putExtra(ManagePermissionsActivity.EXTRA_ALL_PERMISSIONS, true); mActivity.startActivity(intent); break; diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java index 552e1764c..ca649a388 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java @@ -173,7 +173,7 @@ public final class PermissionAppsFragment extends SettingsWithLargeHeader implem final Drawable icon = permissionApps.getIcon(); final CharSequence label = permissionApps.getLabel(); - fragment.setHeader(icon, label, null, true); + fragment.setHeader(icon, label, null, null, true); fragment.setSummary(Utils.getPermissionGroupDescriptionString(fragment.getActivity(), groupName, permissionApps.getDescription()), null); @@ -422,7 +422,7 @@ public final class PermissionAppsFragment extends SettingsWithLargeHeader implem mOuterFragment = (PermissionAppsFragment) getTargetFragment(); setLoading(true /* loading */, false /* animate */); super.onCreate(savedInstanceState); - setHeader(mOuterFragment.mIcon, mOuterFragment.mLabel, null, true); + setHeader(mOuterFragment.mIcon, mOuterFragment.mLabel, null, null, true); if (mOuterFragment.mExtraScreen != null) { setPreferenceScreen(); } else { diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionPreference.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionPreference.java index 20524e113..13a7b997f 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionPreference.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionPreference.java @@ -25,6 +25,7 @@ import android.app.AlertDialog; import android.app.Dialog; import android.content.DialogInterface; import android.os.Bundle; +import android.os.UserHandle; import android.text.BidiFormatter; import android.text.TextUtils; import android.widget.ImageView; @@ -420,7 +421,7 @@ class PermissionPreference extends MultiTargetSwitchPreference { */ private void showAllPermissions(String filterGroup) { Fragment frag = AllAppPermissionsFragment.newInstance(mGroup.getApp().packageName, - filterGroup); + filterGroup, UserHandle.getUserHandleForUid(mGroup.getApp().applicationInfo.uid)); mFragment.getFragmentManager().beginTransaction() .replace(android.R.id.content, frag) .addToBackStack("AllPerms") diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java index 425fe0fa2..07586cd94 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java @@ -435,7 +435,7 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements setHeader(Utils.applyTint(context, context.getDrawable(group.getIconResId()), android.R.attr.colorControlNormal), context.getString(R.string.app_permission_usage_filter_label, - group.getLabel()), null, true); + group.getLabel()), null, null, true); setSummary(context.getString(R.string.app_permission_usage_remove_filter), v -> { onPermissionGroupSelected(null); }); diff --git a/src/com/android/packageinstaller/permission/ui/handheld/ReviewPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/ReviewPermissionsFragment.java index 350448857..77705b879 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/ReviewPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/ReviewPermissionsFragment.java @@ -23,6 +23,7 @@ import android.content.pm.PackageInfo; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.RemoteCallback; +import android.os.UserHandle; import android.text.Html; import android.text.Spanned; import android.text.TextUtils; @@ -151,6 +152,8 @@ public final class ReviewPermissionsFragment extends PreferenceFragmentCompat Intent intent = new Intent(Intent.ACTION_MANAGE_APP_PERMISSIONS); intent.putExtra(Intent.EXTRA_PACKAGE_NAME, mAppPermissions.getPackageInfo().packageName); + intent.putExtra(Intent.EXTRA_USER, UserHandle.getUserHandleForUid( + mAppPermissions.getPackageInfo().applicationInfo.uid)); intent.putExtra(ManagePermissionsActivity.EXTRA_ALL_PERMISSIONS, true); getActivity().startActivity(intent); } diff --git a/src/com/android/packageinstaller/permission/ui/handheld/SettingsWithHeader.java b/src/com/android/packageinstaller/permission/ui/handheld/SettingsWithHeader.java index 6d8f076d6..fef06d5f1 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/SettingsWithHeader.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/SettingsWithHeader.java @@ -19,23 +19,25 @@ package com.android.packageinstaller.permission.ui.handheld; import android.content.Intent; import android.graphics.drawable.Drawable; import android.os.Bundle; +import android.os.UserHandle; import android.view.LayoutInflater; import android.view.View; -import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; +import androidx.annotation.Nullable; + import com.android.packageinstaller.DeviceUtils; import com.android.permissioncontroller.R; -public abstract class SettingsWithHeader extends PermissionsFrameFragment - implements OnClickListener { +public abstract class SettingsWithHeader extends PermissionsFrameFragment { private View mHeader; protected Intent mInfoIntent; protected Drawable mIcon; protected CharSequence mLabel; + protected UserHandle mUserHandle; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, @@ -51,10 +53,12 @@ public abstract class SettingsWithHeader extends PermissionsFrameFragment return root; } - public void setHeader(Drawable icon, CharSequence label, Intent infoIntent) { + public void setHeader(Drawable icon, CharSequence label, Intent infoIntent, + @Nullable UserHandle userHandle) { mIcon = icon; mLabel = label; mInfoIntent = infoIntent; + mUserHandle = userHandle; updateHeader(); } @@ -72,13 +76,9 @@ public abstract class SettingsWithHeader extends PermissionsFrameFragment } else { info.setVisibility(View.VISIBLE); info.setClickable(true); - info.setOnClickListener(this); + info.setOnClickListener(v -> getActivity().startActivityAsUser(mInfoIntent, + mUserHandle)); } } } - - @Override - public void onClick(View v) { - getActivity().startActivity(mInfoIntent); - } } diff --git a/src/com/android/packageinstaller/permission/ui/handheld/SettingsWithLargeHeader.java b/src/com/android/packageinstaller/permission/ui/handheld/SettingsWithLargeHeader.java index c6d107cee..9cd39bc1b 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/SettingsWithLargeHeader.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/SettingsWithLargeHeader.java @@ -19,6 +19,7 @@ package com.android.packageinstaller.permission.ui.handheld; import android.content.Intent; import android.graphics.drawable.Drawable; import android.os.Bundle; +import android.os.UserHandle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -38,6 +39,7 @@ public abstract class SettingsWithLargeHeader extends PermissionsFrameFragment private View mHeader; protected Intent mInfoIntent; + protected UserHandle mUserHandle; protected Drawable mIcon; protected CharSequence mLabel; protected boolean mSmallIcon; @@ -71,10 +73,11 @@ public abstract class SettingsWithLargeHeader extends PermissionsFrameFragment * @param smallIcon whether the icon should be small */ public void setHeader(@NonNull Drawable icon, @NonNull CharSequence label, - Intent infoIntent, boolean smallIcon) { + Intent infoIntent, @Nullable UserHandle userHandle, boolean smallIcon) { mIcon = icon; mLabel = label; mInfoIntent = infoIntent; + mUserHandle = userHandle; mSmallIcon = smallIcon; updateHeader(mHeader); } @@ -96,6 +99,10 @@ public abstract class SettingsWithLargeHeader extends PermissionsFrameFragment appIcon.getLayoutParams().width = size; appIcon.getLayoutParams().height = size; } + if (mInfoIntent != null) { + appIcon.setOnClickListener(v -> getActivity().startActivityAsUser(mInfoIntent, + mUserHandle)); + } TextView appName = header.requireViewById(R.id.entity_header_title); appName.setText(mLabel); -- GitLab From 7f0c7a248dd7a6049cb686fabf8890195f054a16 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Fri, 3 May 2019 10:21:13 -0700 Subject: [PATCH 617/701] Show non-work apps before work apps. Fixes: 131907428 Test: View PermissionAppsFragment with work profile. Change-Id: I153a077232b28a23acc48b9d1e0b5539e025e8e1 --- .../permission/ui/handheld/PermissionAppsFragment.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java index 552e1764c..2ccbc8b15 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java @@ -237,7 +237,13 @@ public final class PermissionAppsFragment extends SettingsWithLargeHeader implem boolean hasPermissionWithBackgroundMode = false; ArrayList sortedApps = new ArrayList<>(permissionApps.getApps()); - sortedApps.sort((x, y) -> mCollator.compare(x.getLabel(), y.getLabel())); + sortedApps.sort((x, y) -> { + int result = mCollator.compare(x.getLabel(), y.getLabel()); + if (result == 0) { + result = x.getUid() - y.getUid(); + } + return result; + }); for (int i = 0; i < sortedApps.size(); i++) { PermissionApp app = sortedApps.get(i); -- GitLab From a1ee14e3bba85e9f99c0d4a11117a5e29dfadd96 Mon Sep 17 00:00:00 2001 From: Evan Severson Date: Fri, 3 May 2019 12:12:07 -0700 Subject: [PATCH 618/701] Change string for Location access check Test: Build Fixes: 131838665 Change-Id: I0e65a8de0eae49e8824bdc37ffe43b1d6c2da2a4 --- res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index d9512f3cf..6129a0d95 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -584,7 +584,7 @@ Permission reminders - %s has been using your location + %s got your location in the background This app can always access your location. Tap to change. -- GitLab From 4839ce14d1b784b13ac841e79df05ffa6f57d885 Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Sat, 4 May 2019 14:04:39 +0800 Subject: [PATCH 619/701] Separate preference inflation and impl for special app access settings. By moving the role-related preference inflation logic into a child fragment. This way we can re-use it for any form factor. Also fixed a memory leak in SpecialAppAccessViewModel. Bug: 124452117 Test: presubmit Change-Id: Ied97a97754ba130a240f6ee9ac94dcbdc7266530 --- .../role/ui/DefaultAppListChildFragment.java | 6 +- .../role/ui/SpecialAppAccessActivity.java | 4 +- ...ava => SpecialAppAccessChildFragment.java} | 111 ++++++++++++------ .../role/ui/SpecialAppAccessListActivity.java | 5 +- ...=> SpecialAppAccessListChildFragment.java} | 76 +++++++----- .../role/ui/SpecialAppAccessViewModel.java | 50 ++++++-- .../AppIconSettingsButtonPreference.java | 10 +- .../ui/handheld/AppIconSwitchPreference.java | 10 +- .../role/ui/handheld/FooterPreference.java | 10 +- .../HandheldSpecialAppAccessFragment.java | 105 +++++++++++++++++ .../HandheldSpecialAppAccessListFragment.java | 80 +++++++++++++ .../role/ui/handheld/SettingsFragment.java | 2 +- 12 files changed, 369 insertions(+), 100 deletions(-) rename src/com/android/packageinstaller/role/ui/{SpecialAppAccessFragment.java => SpecialAppAccessChildFragment.java} (68%) rename src/com/android/packageinstaller/role/ui/{SpecialAppAccessListFragment.java => SpecialAppAccessListChildFragment.java} (65%) create mode 100644 src/com/android/packageinstaller/role/ui/handheld/HandheldSpecialAppAccessFragment.java create mode 100644 src/com/android/packageinstaller/role/ui/handheld/HandheldSpecialAppAccessListFragment.java diff --git a/src/com/android/packageinstaller/role/ui/DefaultAppListChildFragment.java b/src/com/android/packageinstaller/role/ui/DefaultAppListChildFragment.java index 830fc6948..06af0e48d 100644 --- a/src/com/android/packageinstaller/role/ui/DefaultAppListChildFragment.java +++ b/src/com/android/packageinstaller/role/ui/DefaultAppListChildFragment.java @@ -194,7 +194,7 @@ public class DefaultAppListChildFragment type of the parent fragment */ -public class SpecialAppAccessFragment extends SettingsFragment +public class SpecialAppAccessChildFragment extends Fragment implements Preference.OnPreferenceClickListener { - private static final String LOG_TAG = SpecialAppAccessFragment.class.getSimpleName(); - private static final String PREFERENCE_EXTRA_APPLICATION_INFO = - SpecialAppAccessFragment.class.getName() + ".extra.APPLICATION_INFO"; + SpecialAppAccessChildFragment.class.getName() + ".extra.APPLICATION_INFO"; private static final String PREFERENCE_KEY_DESCRIPTION = - SpecialAppAccessFragment.class.getName() + ".preference.DESCRIPTION"; + SpecialAppAccessChildFragment.class.getName() + ".preference.DESCRIPTION"; private String mRoleName; @@ -72,8 +71,8 @@ public class SpecialAppAccessFragment extends SettingsFragment * @return a new instance of this fragment */ @NonNull - public static SpecialAppAccessFragment newInstance(@NonNull String roleName) { - SpecialAppAccessFragment fragment = new SpecialAppAccessFragment(); + public static SpecialAppAccessChildFragment newInstance(@NonNull String roleName) { + SpecialAppAccessChildFragment fragment = new SpecialAppAccessChildFragment(); Bundle arguments = new Bundle(); arguments.putString(Intent.EXTRA_ROLE_NAME, roleName); fragment.setArguments(arguments); @@ -92,9 +91,10 @@ public class SpecialAppAccessFragment extends SettingsFragment public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); + PF preferenceFragment = requirePreferenceFragment(); Activity activity = requireActivity(); mRole = Roles.get(activity).get(mRoleName); - activity.setTitle(mRole.getLabelResource()); + preferenceFragment.setTitle(getString(mRole.getLabelResource())); mViewModel = ViewModelProviders.of(this, new SpecialAppAccessViewModel.Factory(mRole, activity.getApplication())).get(SpecialAppAccessViewModel.class); @@ -102,23 +102,18 @@ public class SpecialAppAccessFragment extends SettingsFragment mViewModel.observeManageRoleHolderState(this, this::onManageRoleHolderStateChanged); } - @Override - @StringRes - protected int getEmptyTextResource() { - return R.string.special_app_access_no_apps; - } - private void onRoleChanged( @NonNull List> qualifyingApplications) { - PreferenceManager preferenceManager = getPreferenceManager(); + PF preferenceFragment = requirePreferenceFragment(); + PreferenceManager preferenceManager = preferenceFragment.getPreferenceManager(); Context context = preferenceManager.getContext(); - PreferenceScreen preferenceScreen = getPreferenceScreen(); + PreferenceScreen preferenceScreen = preferenceFragment.getPreferenceScreen(); Preference oldDescriptionPreference = null; ArrayMap oldPreferences = new ArrayMap<>(); if (preferenceScreen == null) { preferenceScreen = preferenceManager.createPreferenceScreen(context); - setPreferenceScreen(preferenceScreen); + preferenceFragment.setPreferenceScreen(preferenceScreen); } else { oldDescriptionPreference = preferenceScreen.findPreference(PREFERENCE_KEY_DESCRIPTION); for (int i = preferenceScreen.getPreferenceCount() - 1; i >= 0; --i) { @@ -137,10 +132,9 @@ public class SpecialAppAccessFragment extends SettingsFragment String key = qualifyingApplicationInfo.packageName + '_' + qualifyingApplicationInfo.uid; - AppIconSwitchPreference preference = (AppIconSwitchPreference) oldPreferences.get( - key); + TwoStatePreference preference = (TwoStatePreference) oldPreferences.get(key); if (preference == null) { - preference = new AppIconSwitchPreference(context); + preference = preferenceFragment.createApplicationPreference(context); preference.setKey(key); preference.setIcon(Utils.getBadgedIcon(context, qualifyingApplicationInfo)); preference.setTitle(Utils.getAppLabel(qualifyingApplicationInfo, context)); @@ -161,13 +155,13 @@ public class SpecialAppAccessFragment extends SettingsFragment Preference descriptionPreference = oldDescriptionPreference; if (descriptionPreference == null) { - descriptionPreference = new FooterPreference(context); + descriptionPreference = preferenceFragment.createFooterPreference(context); descriptionPreference.setKey(PREFERENCE_KEY_DESCRIPTION); descriptionPreference.setSummary(mRole.getDescriptionResource()); } preferenceScreen.addPreference(descriptionPreference); - updateState(); + preferenceFragment.onPreferenceScreenChanged(); } private void onManageRoleHolderStateChanged(@NonNull ManageRoleHolderStateLiveData liveData, @@ -190,20 +184,59 @@ public class SpecialAppAccessFragment extends SettingsFragment @Override public boolean onPreferenceClick(@NonNull Preference preference) { - String key = preference.getKey(); - ManageRoleHolderStateLiveData liveData = mViewModel.getManageRoleHolderStateLiveData(key, - this); - if (liveData.getValue() != ManageRoleHolderStateLiveData.STATE_IDLE) { - Log.i(LOG_TAG, "Trying to set special app access while another request is on-going"); - return true; - } - ApplicationInfo applicationInfo = preference.getExtras().getParcelable( PREFERENCE_EXTRA_APPLICATION_INFO); String packageName = applicationInfo.packageName; UserHandle user = UserHandle.getUserHandleForUid(applicationInfo.uid); - boolean add = !((AppIconSwitchPreference) preference).isChecked(); - liveData.setRoleHolderAsUser(mRoleName, packageName, add, 0, user, requireContext()); + boolean allow = !((TwoStatePreference) preference).isChecked(); + String key = preference.getKey(); + mViewModel.setSpecialAppAccessAsUser(packageName, allow, user, key, this, + this::onManageRoleHolderStateChanged); return true; } + + @NonNull + private PF requirePreferenceFragment() { + //noinspection unchecked + return (PF) requireParentFragment(); + } + + /** + * Interface that the parent fragment must implement. + */ + public interface Parent { + + /** + * Set the title of the current settings page. + * + * @param title the title of the current settings page + */ + void setTitle(@NonNull CharSequence title); + + /** + * Create a new preference for an application. + * + * @param context the {@code Context} to use when creating the preference. + * + * @return a new preference for an application + */ + @NonNull + TwoStatePreference createApplicationPreference(@NonNull Context context); + + /** + * Create a new preference for the footer. + * + * @param context the {@code Context} to use when creating the preference. + * + * @return a new preference for the footer + */ + @NonNull + Preference createFooterPreference(@NonNull Context context); + + /** + * Callback when changes have been made to the {@link PreferenceScreen} of the parent + * {@link PreferenceFragmentCompat}. + */ + void onPreferenceScreenChanged(); + } } diff --git a/src/com/android/packageinstaller/role/ui/SpecialAppAccessListActivity.java b/src/com/android/packageinstaller/role/ui/SpecialAppAccessListActivity.java index 2bf6c9278..6997375f0 100644 --- a/src/com/android/packageinstaller/role/ui/SpecialAppAccessListActivity.java +++ b/src/com/android/packageinstaller/role/ui/SpecialAppAccessListActivity.java @@ -22,6 +22,8 @@ import android.view.WindowManager; import androidx.annotation.Nullable; import androidx.fragment.app.FragmentActivity; +import com.android.packageinstaller.role.ui.handheld.HandheldSpecialAppAccessListFragment; + /** * Activity for the list of special app accesses. */ @@ -35,7 +37,8 @@ public class SpecialAppAccessListActivity extends FragmentActivity { WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS); if (savedInstanceState == null) { - SpecialAppAccessListFragment fragment = SpecialAppAccessListFragment.newInstance(); + HandheldSpecialAppAccessListFragment fragment = + HandheldSpecialAppAccessListFragment.newInstance(); getSupportFragmentManager().beginTransaction() .add(android.R.id.content, fragment) .commit(); diff --git a/src/com/android/packageinstaller/role/ui/SpecialAppAccessListFragment.java b/src/com/android/packageinstaller/role/ui/SpecialAppAccessListChildFragment.java similarity index 65% rename from src/com/android/packageinstaller/role/ui/SpecialAppAccessListFragment.java rename to src/com/android/packageinstaller/role/ui/SpecialAppAccessListChildFragment.java index c3d9e9804..2f9eb2d8c 100644 --- a/src/com/android/packageinstaller/role/ui/SpecialAppAccessListFragment.java +++ b/src/com/android/packageinstaller/role/ui/SpecialAppAccessListChildFragment.java @@ -25,28 +25,28 @@ import android.util.ArrayMap; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.annotation.StringRes; +import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProviders; import androidx.preference.Preference; +import androidx.preference.PreferenceFragmentCompat; import androidx.preference.PreferenceManager; import androidx.preference.PreferenceScreen; import com.android.packageinstaller.role.model.Role; import com.android.packageinstaller.role.model.Roles; -import com.android.packageinstaller.role.ui.handheld.AppIconSettingsButtonPreference; -import com.android.packageinstaller.role.ui.handheld.SettingsFragment; -import com.android.permissioncontroller.R; import java.util.List; /** - * Fragment for the list of special app accesses. + * Child fragment for the list of special app accesses. Must be added as a child fragment and its + * parent fragment must be a {@link PreferenceFragmentCompat} which implements {@link Parent}. + * + * @param type of the parent fragment */ -public class SpecialAppAccessListFragment extends SettingsFragment +public class SpecialAppAccessListChildFragment extends Fragment implements Preference.OnPreferenceClickListener { - private static final String LOG_TAG = SpecialAppAccessListFragment.class.getSimpleName(); - private SpecialAppAccessListViewModel mViewModel; /** @@ -55,8 +55,8 @@ public class SpecialAppAccessListFragment extends SettingsFragment * @return a new instance of this fragment */ @NonNull - public static SpecialAppAccessListFragment newInstance() { - return new SpecialAppAccessListFragment(); + public static SpecialAppAccessListChildFragment newInstance() { + return new SpecialAppAccessListChildFragment(); } @Override @@ -67,30 +67,20 @@ public class SpecialAppAccessListFragment extends SettingsFragment mViewModel.getLiveData().observe(this, roleItems -> onRoleListChanged()); } - @Override - @StringRes - protected int getEmptyTextResource() { - return R.string.no_special_app_access; - } - - @Override - protected int getHelpUriResource() { - return R.string.help_uri_special_app_access; - } - private void onRoleListChanged() { List roleItems = mViewModel.getLiveData().getValue(); if (roleItems == null) { return; } - PreferenceManager preferenceManager = getPreferenceManager(); + PF preferenceFragment = requirePreferenceFragment(); + PreferenceManager preferenceManager = preferenceFragment.getPreferenceManager(); Context context = preferenceManager.getContext(); - PreferenceScreen preferenceScreen = getPreferenceScreen(); + PreferenceScreen preferenceScreen = preferenceFragment.getPreferenceScreen(); ArrayMap oldPreferences = new ArrayMap<>(); if (preferenceScreen == null) { preferenceScreen = preferenceManager.createPreferenceScreen(context); - setPreferenceScreen(preferenceScreen); + preferenceFragment.setPreferenceScreen(preferenceScreen); } else { for (int i = preferenceScreen.getPreferenceCount() - 1; i >= 0; --i) { Preference preference = preferenceScreen.getPreference(i); @@ -104,10 +94,10 @@ public class SpecialAppAccessListFragment extends SettingsFragment RoleItem roleItem = roleItems.get(i); Role role = roleItem.getRole(); - AppIconSettingsButtonPreference preference = - (AppIconSettingsButtonPreference) oldPreferences.get(role.getName()); + TwoTargetPreference preference = (TwoTargetPreference) oldPreferences.get( + role.getName()); if (preference == null) { - preference = new AppIconSettingsButtonPreference(context); + preference = preferenceFragment.createPreference(context); preference.setKey(role.getName()); preference.setIconSpaceReserved(true); preference.setTitle(role.getShortLabelResource()); @@ -120,7 +110,7 @@ public class SpecialAppAccessListFragment extends SettingsFragment preferenceScreen.addPreference(preference); } - updateState(); + preferenceFragment.onPreferenceScreenChanged(); } @Override @@ -131,9 +121,37 @@ public class SpecialAppAccessListFragment extends SettingsFragment UserHandle user = Process.myUserHandle(); Intent intent = role.getManageIntentAsUser(user, context); if (intent == null) { - intent = SpecialAppAccessActivity.createIntent(roleName, requireContext()); + intent = SpecialAppAccessActivity.createIntent(roleName, context); } startActivity(intent); return true; } + + @NonNull + private PF requirePreferenceFragment() { + //noinspection unchecked + return (PF) requireParentFragment(); + } + + /** + * Interface that the parent fragment must implement. + */ + public interface Parent { + + /** + * Create a new preference for a special app access. + * + * @param context the {@code Context} to use when creating the preference. + * + * @return a new preference for a special app access + */ + @NonNull + TwoTargetPreference createPreference(@NonNull Context context); + + /** + * Callback when changes have been made to the {@link PreferenceScreen} of the parent + * {@link PreferenceFragmentCompat}. + */ + void onPreferenceScreenChanged(); + } } diff --git a/src/com/android/packageinstaller/role/ui/SpecialAppAccessViewModel.java b/src/com/android/packageinstaller/role/ui/SpecialAppAccessViewModel.java index 64f0e72e8..eb6624a8f 100644 --- a/src/com/android/packageinstaller/role/ui/SpecialAppAccessViewModel.java +++ b/src/com/android/packageinstaller/role/ui/SpecialAppAccessViewModel.java @@ -21,6 +21,7 @@ import android.content.pm.ApplicationInfo; import android.os.Process; import android.os.UserHandle; import android.util.ArrayMap; +import android.util.Log; import android.util.Pair; import androidx.annotation.NonNull; @@ -37,10 +38,15 @@ import com.android.packageinstaller.role.utils.UserUtils; import java.util.List; /** - * {@link ViewModel} for a default app. + * {@link ViewModel} for a special app access. */ public class SpecialAppAccessViewModel extends AndroidViewModel { + private static final String LOG_TAG = SpecialAppAccessViewModel.class.getSimpleName(); + + @NonNull + private final Role mRole; + @NonNull private final LiveData>> mRoleLiveData; @@ -48,11 +54,11 @@ public class SpecialAppAccessViewModel extends AndroidViewModel { private final ArrayMap mManageRoleHolderStateLiveDatas = new ArrayMap<>(); - private ManageRoleHolderStateObserver mManageRoleHolderStateObserver; - public SpecialAppAccessViewModel(@NonNull Role role, @NonNull Application application) { super(application); + mRole = role; + UserHandle user = Process.myUserHandle(); RoleLiveData roleLiveData = new RoleLiveData(role, user, application); UserHandle workProfile = UserUtils.getWorkProfile(application); @@ -79,14 +85,12 @@ public class SpecialAppAccessViewModel extends AndroidViewModel { */ public void observeManageRoleHolderState(@NonNull LifecycleOwner owner, @NonNull ManageRoleHolderStateObserver observer) { - mManageRoleHolderStateObserver = observer; - int manageRoleHolderStateLiveDatasSize = mManageRoleHolderStateLiveDatas.size(); for (int i = 0; i < manageRoleHolderStateLiveDatasSize; i++) { ManageRoleHolderStateLiveData liveData = mManageRoleHolderStateLiveDatas.valueAt(i); - liveData.observe(owner, state -> mManageRoleHolderStateObserver - .onManageRoleHolderStateChanged(liveData, state)); + liveData.observe(owner, state -> observer.onManageRoleHolderStateChanged(liveData, + state)); } } @@ -95,23 +99,47 @@ public class SpecialAppAccessViewModel extends AndroidViewModel { * * @param key the key for the {@link ManageRoleHolderStateLiveData} * @param owner the {@link LifecycleOwner} which controls the observer + * @param observer the observer that will receive the events * * @return the {@link ManageRoleHolderStateLiveData} */ @NonNull - public ManageRoleHolderStateLiveData getManageRoleHolderStateLiveData( - @NonNull String key, @NonNull LifecycleOwner owner) { + private ManageRoleHolderStateLiveData getManageRoleHolderStateLiveData(@NonNull String key, + @NonNull LifecycleOwner owner, @NonNull ManageRoleHolderStateObserver observer) { ManageRoleHolderStateLiveData liveData = mManageRoleHolderStateLiveDatas.get(key); if (liveData == null) { liveData = new ManageRoleHolderStateLiveData(); ManageRoleHolderStateLiveData finalLiveData = liveData; - liveData.observe(owner, state -> mManageRoleHolderStateObserver - .onManageRoleHolderStateChanged(finalLiveData, state)); + liveData.observe(owner, state -> observer.onManageRoleHolderStateChanged(finalLiveData, + state)); mManageRoleHolderStateLiveDatas.put(key, liveData); } return liveData; } + /** + * Set whether an application has an special app access. + * + * @param packageName the package name of the application + * @param allow whether the application should have the access + * @param user the user of the application + * @param key the key for the {@link ManageRoleHolderStateLiveData} + * @param owner the {@link LifecycleOwner} which controls the observer + * @param observer the observer that will receive the events + */ + public void setSpecialAppAccessAsUser(@NonNull String packageName, boolean allow, + @NonNull UserHandle user, @NonNull String key, @NonNull LifecycleOwner owner, + @NonNull ManageRoleHolderStateObserver observer) { + ManageRoleHolderStateLiveData liveData = getManageRoleHolderStateLiveData(key, owner, + observer); + if (liveData.getValue() != ManageRoleHolderStateLiveData.STATE_IDLE) { + Log.i(LOG_TAG, "Trying to set special app access while another request is on-going"); + return; + } + liveData.setRoleHolderAsUser(mRole.getName(), packageName, allow, 0, user, + getApplication()); + } + /** * Observer for multiple {@link ManageRoleHolderStateLiveData} instances. */ diff --git a/src/com/android/packageinstaller/role/ui/handheld/AppIconSettingsButtonPreference.java b/src/com/android/packageinstaller/role/ui/handheld/AppIconSettingsButtonPreference.java index 3e02aebc7..cd2dcd366 100644 --- a/src/com/android/packageinstaller/role/ui/handheld/AppIconSettingsButtonPreference.java +++ b/src/com/android/packageinstaller/role/ui/handheld/AppIconSettingsButtonPreference.java @@ -28,31 +28,31 @@ import androidx.preference.PreferenceViewHolder; /** * {@link SettingsButtonPreference} with {@link AppIconPreference.Mixin}. */ -public class AppIconSettingsButtonPreference extends SettingsButtonPreference { +class AppIconSettingsButtonPreference extends SettingsButtonPreference { private AppIconPreference.Mixin mMixin; - public AppIconSettingsButtonPreference(@NonNull Context context, @Nullable AttributeSet attrs, + AppIconSettingsButtonPreference(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr, @StyleRes int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); init(); } - public AppIconSettingsButtonPreference(@NonNull Context context, @Nullable AttributeSet attrs, + AppIconSettingsButtonPreference(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } - public AppIconSettingsButtonPreference(@NonNull Context context, @Nullable AttributeSet attrs) { + AppIconSettingsButtonPreference(@NonNull Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(); } - public AppIconSettingsButtonPreference(@NonNull Context context) { + AppIconSettingsButtonPreference(@NonNull Context context) { super(context); init(); diff --git a/src/com/android/packageinstaller/role/ui/handheld/AppIconSwitchPreference.java b/src/com/android/packageinstaller/role/ui/handheld/AppIconSwitchPreference.java index 151778d69..de3f4844d 100644 --- a/src/com/android/packageinstaller/role/ui/handheld/AppIconSwitchPreference.java +++ b/src/com/android/packageinstaller/role/ui/handheld/AppIconSwitchPreference.java @@ -29,31 +29,31 @@ import androidx.preference.SwitchPreference; /** * {@link SwitchPreference} with {@link AppIconPreference.Mixin}. */ -public class AppIconSwitchPreference extends SwitchPreference { +class AppIconSwitchPreference extends SwitchPreference { private AppIconPreference.Mixin mMixin; - public AppIconSwitchPreference(@NonNull Context context, @Nullable AttributeSet attrs, + AppIconSwitchPreference(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr, @StyleRes int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); init(); } - public AppIconSwitchPreference(@NonNull Context context, @Nullable AttributeSet attrs, + AppIconSwitchPreference(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } - public AppIconSwitchPreference(@NonNull Context context, @Nullable AttributeSet attrs) { + AppIconSwitchPreference(@NonNull Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(); } - public AppIconSwitchPreference(@NonNull Context context) { + AppIconSwitchPreference(@NonNull Context context) { super(context); init(); diff --git a/src/com/android/packageinstaller/role/ui/handheld/FooterPreference.java b/src/com/android/packageinstaller/role/ui/handheld/FooterPreference.java index 92fa94ac2..bcdab36f8 100644 --- a/src/com/android/packageinstaller/role/ui/handheld/FooterPreference.java +++ b/src/com/android/packageinstaller/role/ui/handheld/FooterPreference.java @@ -35,31 +35,31 @@ import com.android.permissioncontroller.R; /** * {@link Preference} acting as the footer of a page. */ -public class FooterPreference extends Preference { +class FooterPreference extends Preference { private static final int ICON_LAYOUT_PADDING_VERTICAL_DP = 16; - public FooterPreference(@NonNull Context context, @Nullable AttributeSet attrs, + FooterPreference(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr, @StyleRes int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); init(); } - public FooterPreference(@NonNull Context context, @Nullable AttributeSet attrs, + FooterPreference(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } - public FooterPreference(@NonNull Context context, @Nullable AttributeSet attrs) { + FooterPreference(@NonNull Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(); } - public FooterPreference(@NonNull Context context) { + FooterPreference(@NonNull Context context) { super(context); init(); diff --git a/src/com/android/packageinstaller/role/ui/handheld/HandheldSpecialAppAccessFragment.java b/src/com/android/packageinstaller/role/ui/handheld/HandheldSpecialAppAccessFragment.java new file mode 100644 index 000000000..52fdc03dc --- /dev/null +++ b/src/com/android/packageinstaller/role/ui/handheld/HandheldSpecialAppAccessFragment.java @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2019 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.packageinstaller.role.ui.handheld; + +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.StringRes; +import androidx.preference.Preference; +import androidx.preference.TwoStatePreference; + +import com.android.packageinstaller.role.ui.SpecialAppAccessChildFragment; +import com.android.permissioncontroller.R; + +/** + * Handheld fragment for a special app access. + */ +public class HandheldSpecialAppAccessFragment extends SettingsFragment + implements SpecialAppAccessChildFragment.Parent { + + private String mRoleName; + + /** + * Create a new instance of this fragment. + * + * @param roleName the name of the role for the special app access + * + * @return a new instance of this fragment + */ + @NonNull + public static HandheldSpecialAppAccessFragment newInstance(@NonNull String roleName) { + HandheldSpecialAppAccessFragment fragment = new HandheldSpecialAppAccessFragment(); + Bundle arguments = new Bundle(); + arguments.putString(Intent.EXTRA_ROLE_NAME, roleName); + fragment.setArguments(arguments); + return fragment; + } + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + Bundle arguments = getArguments(); + mRoleName = arguments.getString(Intent.EXTRA_ROLE_NAME); + } + + @Override + public void onActivityCreated(@Nullable Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + if (savedInstanceState == null) { + SpecialAppAccessChildFragment fragment = SpecialAppAccessChildFragment.newInstance( + mRoleName); + getChildFragmentManager().beginTransaction() + .add(fragment, null) + .commit(); + } + } + + @Override + @StringRes + protected int getEmptyTextResource() { + return R.string.special_app_access_no_apps; + } + + @Override + public void setTitle(@NonNull CharSequence title) { + requireActivity().setTitle(title); + } + + @NonNull + @Override + public TwoStatePreference createApplicationPreference(@NonNull Context context) { + return new AppIconSwitchPreference(context); + } + + @NonNull + @Override + public Preference createFooterPreference(@NonNull Context context) { + return new FooterPreference(context); + } + + + @Override + public void onPreferenceScreenChanged() { + updateState(); + } +} diff --git a/src/com/android/packageinstaller/role/ui/handheld/HandheldSpecialAppAccessListFragment.java b/src/com/android/packageinstaller/role/ui/handheld/HandheldSpecialAppAccessListFragment.java new file mode 100644 index 000000000..3c6975550 --- /dev/null +++ b/src/com/android/packageinstaller/role/ui/handheld/HandheldSpecialAppAccessListFragment.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2019 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.packageinstaller.role.ui.handheld; + +import android.content.Context; +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.StringRes; + +import com.android.packageinstaller.role.ui.SpecialAppAccessListChildFragment; +import com.android.packageinstaller.role.ui.TwoTargetPreference; +import com.android.permissioncontroller.R; + +/** + * Handheld fragment for the list of special app accesses. + */ +public class HandheldSpecialAppAccessListFragment extends SettingsFragment + implements SpecialAppAccessListChildFragment.Parent { + + /** + * Create a new instance of this fragment. + * + * @return a new instance of this fragment + */ + @NonNull + public static HandheldSpecialAppAccessListFragment newInstance() { + return new HandheldSpecialAppAccessListFragment(); + } + + @Override + public void onActivityCreated(@Nullable Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + if (savedInstanceState == null) { + SpecialAppAccessListChildFragment fragment = + SpecialAppAccessListChildFragment.newInstance(); + getChildFragmentManager().beginTransaction() + .add(fragment, null) + .commit(); + } + } + + @Override + @StringRes + protected int getEmptyTextResource() { + return R.string.no_special_app_access; + } + + @Override + protected int getHelpUriResource() { + return R.string.help_uri_special_app_access; + } + + @NonNull + @Override + public TwoTargetPreference createPreference(@NonNull Context context) { + return new AppIconSettingsButtonPreference(context); + } + + @Override + public void onPreferenceScreenChanged() { + updateState(); + } +} diff --git a/src/com/android/packageinstaller/role/ui/handheld/SettingsFragment.java b/src/com/android/packageinstaller/role/ui/handheld/SettingsFragment.java index e37b8b210..26180dadd 100644 --- a/src/com/android/packageinstaller/role/ui/handheld/SettingsFragment.java +++ b/src/com/android/packageinstaller/role/ui/handheld/SettingsFragment.java @@ -41,7 +41,7 @@ import com.android.settingslib.HelpUtils; /** * Base class for settings fragments. */ -public abstract class SettingsFragment extends PreferenceFragmentCompat { +abstract class SettingsFragment extends PreferenceFragmentCompat { private FrameLayout mContentLayout; private LinearLayout mPreferenceLayout; -- GitLab From 57ad2df367dca77c959a9dbf27fac62e7af77a5d Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Sat, 4 May 2019 12:52:38 -0700 Subject: [PATCH 620/701] Import translations. DO NOT MERGE Auto-generated-cl: translation import Bug: 64712476 Change-Id: I653fae4190b651d7cdf05611534b3561170f7a8d --- res/values-af/strings.xml | 26 ++++++++++++++++++-- res/values-am/strings.xml | 26 ++++++++++++++++++-- res/values-ar/strings.xml | 26 ++++++++++++++++++-- res/values-as/strings.xml | 26 ++++++++++++++++++-- res/values-az/strings.xml | 28 ++++++++++++++++++--- res/values-b+sr+Latn/strings.xml | 26 ++++++++++++++++++-- res/values-be/strings.xml | 26 ++++++++++++++++++-- res/values-bg/strings.xml | 26 ++++++++++++++++++-- res/values-bn/strings.xml | 30 ++++++++++++++++++++--- res/values-bs/strings.xml | 26 ++++++++++++++++++-- res/values-ca/strings.xml | 26 ++++++++++++++++++-- res/values-cs/strings.xml | 28 ++++++++++++++++++--- res/values-da/strings.xml | 26 ++++++++++++++++++-- res/values-de/strings.xml | 28 ++++++++++++++++++--- res/values-el/strings.xml | 26 ++++++++++++++++++-- res/values-en-rAU/strings.xml | 26 ++++++++++++++++++-- res/values-en-rCA/strings.xml | 26 ++++++++++++++++++-- res/values-en-rGB/strings.xml | 26 ++++++++++++++++++-- res/values-en-rIN/strings.xml | 26 ++++++++++++++++++-- res/values-en-rXC/strings.xml | 26 ++++++++++++++++++-- res/values-es-rUS/strings.xml | 34 +++++++++++++++++++++----- res/values-es/strings.xml | 26 ++++++++++++++++++-- res/values-et/strings.xml | 26 ++++++++++++++++++-- res/values-eu/strings.xml | 26 ++++++++++++++++++-- res/values-fa/strings.xml | 28 ++++++++++++++++++--- res/values-fi/strings.xml | 26 ++++++++++++++++++-- res/values-fr-rCA/strings.xml | 32 ++++++++++++++++++++---- res/values-fr/strings.xml | 32 ++++++++++++++++++++---- res/values-gl/strings.xml | 36 +++++++++++++++++++++------ res/values-gu/strings.xml | 28 ++++++++++++++++++--- res/values-hi/strings.xml | 26 ++++++++++++++++++-- res/values-hr/strings.xml | 26 ++++++++++++++++++-- res/values-hu/strings.xml | 26 ++++++++++++++++++-- res/values-hy/strings.xml | 26 ++++++++++++++++++-- res/values-in/strings.xml | 26 ++++++++++++++++++-- res/values-is/strings.xml | 26 ++++++++++++++++++-- res/values-it/strings.xml | 26 ++++++++++++++++++-- res/values-iw/strings.xml | 28 ++++++++++++++++++--- res/values-ja/strings.xml | 26 ++++++++++++++++++-- res/values-ka/strings.xml | 26 ++++++++++++++++++-- res/values-kk/strings.xml | 26 ++++++++++++++++++-- res/values-km/strings.xml | 26 ++++++++++++++++++-- res/values-kn/strings.xml | 28 ++++++++++++++++++--- res/values-ko/strings.xml | 26 ++++++++++++++++++-- res/values-ky/strings.xml | 26 ++++++++++++++++++-- res/values-lo/strings.xml | 26 ++++++++++++++++++-- res/values-lt/strings.xml | 26 ++++++++++++++++++-- res/values-lv/strings.xml | 26 ++++++++++++++++++-- res/values-mk/strings.xml | 26 ++++++++++++++++++-- res/values-ml/strings.xml | 28 ++++++++++++++++++--- res/values-mn/strings.xml | 26 ++++++++++++++++++-- res/values-mr/strings.xml | 42 ++++++++++++++++++++++++-------- res/values-ms/strings.xml | 26 ++++++++++++++++++-- res/values-my/strings.xml | 26 ++++++++++++++++++-- res/values-nb/strings.xml | 30 ++++++++++++++++++++--- res/values-ne/strings.xml | 26 ++++++++++++++++++-- res/values-nl/strings.xml | 26 ++++++++++++++++++-- res/values-or/strings.xml | 36 +++++++++++++++++++++------ res/values-pa/strings.xml | 28 ++++++++++++++++++--- res/values-pl/strings.xml | 26 ++++++++++++++++++-- res/values-pt-rBR/strings.xml | 26 ++++++++++++++++++-- res/values-pt-rPT/strings.xml | 26 ++++++++++++++++++-- res/values-pt/strings.xml | 26 ++++++++++++++++++-- res/values-ro/strings.xml | 26 ++++++++++++++++++-- res/values-ru/strings.xml | 26 ++++++++++++++++++-- res/values-si/strings.xml | 26 ++++++++++++++++++-- res/values-sk/strings.xml | 26 ++++++++++++++++++-- res/values-sl/strings.xml | 26 ++++++++++++++++++-- res/values-sq/strings.xml | 26 ++++++++++++++++++-- res/values-sr/strings.xml | 26 ++++++++++++++++++-- res/values-sv/strings.xml | 26 ++++++++++++++++++-- res/values-sw/strings.xml | 26 ++++++++++++++++++-- res/values-ta/strings.xml | 26 ++++++++++++++++++-- res/values-te/strings.xml | 34 +++++++++++++++++++++----- res/values-th/strings.xml | 26 ++++++++++++++++++-- res/values-tl/strings.xml | 26 ++++++++++++++++++-- res/values-tr/strings.xml | 26 ++++++++++++++++++-- res/values-uk/strings.xml | 26 ++++++++++++++++++-- res/values-ur/strings.xml | 26 ++++++++++++++++++-- res/values-uz/strings.xml | 26 ++++++++++++++++++-- res/values-vi/strings.xml | 26 ++++++++++++++++++-- res/values-zh-rCN/strings.xml | 26 ++++++++++++++++++-- res/values-zh-rHK/strings.xml | 28 ++++++++++++++++++--- res/values-zh-rTW/strings.xml | 26 ++++++++++++++++++-- res/values-zu/strings.xml | 26 ++++++++++++++++++-- 85 files changed, 2086 insertions(+), 216 deletions(-) diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml index 5ae114445..cb0cfb19c 100644 --- a/res/values-af/strings.xml +++ b/res/values-af/strings.xml @@ -145,8 +145,30 @@ "Weier" "%1$s-toestemming" "%1$s-toegang vir hierdie program" - "%1$s het %3$s gelede toegang tot jou %2$s verkry" - "%1$s het nie toegang gekry tot jou %2$s nie" + "%1$s het %3$s gelede by jou %2$s ingegaan" + "%1$s het %2$s gelede by jou fisieke aktiwiteit ingegaan" + "%1$s het %2$s gelede by jou kalender ingegaan" + "%1$s het %2$s gelede by jou oproeprekords ingegaan" + "%1$s het %2$s gelede by jou kamera ingegaan" + "%1$s het %2$s gelede by jou kontakte ingegaan" + "%1$s het %2$s gelede by jou ligging ingegaan" + "%1$s het %2$s gelede by jou mikrofoon ingegaan" + "%1$s het %2$s gelede by jou foon ingegaan" + "%1$s het %2$s gelede by jou sensors ingegaan" + "%1$s het %2$s gelede by jou SMS ingegaan" + "%1$s het %2$s gelede by jou berging ingegaan" + "%1$s het nie by jou %2$s ingegaan nie" + "%1$s het nie by jou fisieke aktiwiteit ingegaan nie" + "%1$s het nie by jou kalender ingegaan nie" + "%1$s het nie by jou oproeprekords ingegaan nie" + "%1$s het nie by jou kamera ingegaan nie" + "%1$s het nie by jou kontakte ingegaan nie" + "%1$s het nie by jou ligging ingegaan nie" + "%1$s het nie by jou mikrofoon ingegaan nie" + "%1$s het nie by jou foon ingegaan nie" + "%1$s het nie by jou sensors ingegaan nie" + "%1$s het nie by jou SMS ingegaan nie" + "%1$s het nie by jou berging ingegaan nie" "Laaste toegangdata is nie tans vir hierdie toestemming beskikbaar nie" "Sien al %1$s se toestemmings" "Sien alle programme met hierdie toestemming" diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml index d195888bf..c93ab9ef4 100644 --- a/res/values-am/strings.xml +++ b/res/values-am/strings.xml @@ -145,8 +145,30 @@ "ከልክል" "የ%1$s ፈቃድ" "%1$s መዳረሻ ለዚህ መተግበሪያ" - "%1$s%3$s በፊት የእርስዎን %2$s ደርሶ ነበር" - "%1$s የእርስዎን %2$s አልደረሰበትም" + "%1$s የእርስዎን %2$s%3$s በፊት ደርሶበታል" + "%1$s የእርስዎን አካላዊ እንቅስቃሴ ከ%2$s በፊት ደርሶበታል" + "%1$s የእርስዎን ቀን መቁጠሪያ ከ%2$s በፊት ደርሶበታል" + "%1$s የእርስዎን የጥሪ ምዝግብ ማስታወሻዎች ከ%2$s በፊት ደርሶበታል" + "%1$s የእርስዎን ካሜራ ከ%2$s በፊት ደርሶበታል" + "%1$s የእርስዎን እውቂያዎች ከ%2$s በፊት ደርሶበታል" + "%1$s የእርስዎን አካባቢ ከ%2$s በፊት ደርሶበታል" + "%1$s የእርስዎን ማይክሮፎን ከ%2$s በፊት ደርሶበታል" + "%1$s የእርስዎን ስልክ ከ%2$s በፊት ደርሶበታል" + "%1$s የእርስዎን ዳሳሾች ከ%2$s በፊት ደርሶበታል" + "%1$s የእርስዎን ኤስኤምኤስ ከ%2$s በፊት ደርሶበታል" + "%1$s የእርስዎን ማከማቻ ከ%2$s በፊት ደርሶበታል" + "%1$s የእርስዎን %2$s አልደረሰበትም" + "%1$s የእርስዎን አካላዊ እንቅስቃሴ አልደረሰበትም" + "%1$s የእርስዎን ቀን መቁጠሪያ አልደረሰበትም" + "%1$s የእርስዎን የጥሪ ምዝግብ ማስታወሻዎች አልደረሰባቸውም" + "%1$s የእርስዎን ካሜራ አልደረሰበትም" + "%1$s የእርስዎን እውቂያዎች አልደረሰበትም" + "%1$s የእርስዎን አካባቢ አልደረሰበትም" + "%1$s የእርስዎን ማይክሮፎን አልደረሰበትም" + "%1$s የእርስዎን ስልክ አልደረሰበትም" + "%1$s የእርስዎን ዳሳሾች አልደረሰበትም" + "%1$s የእርስዎን ኤስኤምኤስ አልደረሰበትም" + "%1$s የእርስዎን ማከማቻ አልደረሰበትም" "የመጨረሻው የመዳረሻ ውሂብ በአሁኑ ጊዜ ለዚህ ፈቃድ አይገኝም" "ሁሉንም %1$s ፈቃዶች ይመልከቱ" "ከዚህ መተግበሪያ ጋር ሁሉንም መተግበሪያዎች ይመልከቱ" diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml index 394cc46df..49e8d0478 100644 --- a/res/values-ar/strings.xml +++ b/res/values-ar/strings.xml @@ -157,8 +157,30 @@ "رفض" "إذن %1$s" "منح هذا التطبيق الإذن بالوصول إلى %1$s" - "قبل %3$s، استخدَم تطبيق %1$s إذن %2$s الذي منحته." - "لم يستخدم تطبيق \"%1$s\" إذن %2$s حتى الآن." + "حصل تطبيق %1$s على إذن بالدخول إلى %2$s قبل %3$s." + "حصل تطبيق %1$s على إذن بالدخول إلى نشاطك البدني قبل %2$s." + "حصل تطبيق %1$s على إذن بالدخول إلى التقويم قبل %2$s." + "حصل تطبيق %1$s على إذن بالدخول إلى سجّلات المكالمات قبل %2$s." + "حصل تطبيق %1$s على إذن بالدخول إلى الكاميرا قبل %2$s." + "حصل تطبيق %1$s على إذن بالدخول إلى جهات الاتصال قبل %2$s." + "حصل تطبيق %1$s على إذن بالدخول إلى الموقع الجغرافي قبل %2$s." + "حصل تطبيق %1$s على إذن بالدخول إلى الميكروفون قبل %2$s." + "حصل تطبيق %1$s على إذن بالدخول إلى هاتفك قبل %2$s." + "حصل تطبيق %1$s على إذن بالدخول إلى أجهزة الاستشعار قبل %2$s." + "‏حصل تطبيق %1$s على إذن بالدخول إلى رسائل SMS قبل %2$s." + "حصل تطبيق %1$s على إذن بالدخول إلى سعة التخزين قبل %2$s." + "لم يحصل تطبيق %1$s على إذن بالدخول إلى %2$s." + "لم يحصل تطبيق %1$s على إذن بالدخول إلى نشاطك البدني." + "لم يحصل تطبيق %1$s على إذن بالدخول إلى التقويم." + "لم يحصل تطبيق %1$s على إذن بالدخول إلى سجّلات المكالمات." + "لم يحصل تطبيق %1$s على إذن بالدخول إلى الكاميرا." + "لم يحصل تطبيق %1$s على إذن بالدخول إلى جهات اتصالك." + "لم يحصل تطبيق %1$s على إذن بالدخول إلى الموقع الجغرافي." + "لم يحصل تطبيق %1$s على إذن بالدخول إلى الميكروفون." + "لم يحصل تطبيق %1$s على إذن بالدخول إلى هاتفك." + "لم يحصل تطبيق %1$s على إذن بالدخول إلى أجهزة الاستشعار." + "‏لم يحصل تطبيق %1$s على إذن بالدخول إلى رسائل SMS." + "لم يحصل تطبيق %1$s على إذن بالدخول إلى مساحة التخزين." "لا تتوفَّر بيانات آخر وصول لهذا الإذن." "الاطّلاع على جميع أذونات %1$s" "الاطّلاع على جميع التطبيقات التي لديها هذا الإذن" diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml index d10963331..4b7cc71c8 100644 --- a/res/values-as/strings.xml +++ b/res/values-as/strings.xml @@ -145,8 +145,30 @@ "অস্বীকাৰ কৰক" "%1$s অনুমতি" "এই এপ্‌টোৰ বাবে %1$sৰ এক্সেছ" - "%1$s%3$s পূর্বে আপোনাৰ %2$s এক্সেছ কৰিছিল" - "%1$sএ আপোনাৰ %2$s এক্সেছ কৰা নাই" + "%1$s%3$s পূৰ্বে আপোনাৰ %2$s এক্সেছ কৰিছিল" + "%1$s%2$s পূৰ্বে আপোনাৰ শাৰীৰিক কাৰ্যকলাপ এক্সেছ কৰিছিল" + "%1$s%2$s পূর্বে আপোনাৰ কেলেণ্ডাৰ এক্সেছ কৰিছিল" + "%1$s%2$s পূৰ্বে আপোনাৰ কল লগ এক্সেছ কৰিছিল" + "%1$s%2$s পূৰ্বে আপোনাৰ কেমেৰা এক্সেছ কৰিছিল" + "%1$s%2$s পূর্বে আপোনাৰ সম্পৰ্কসূচী এক্সেছ কৰিছিল" + "%1$s%2$s পূৰ্বে আপোনাৰ অৱস্থান এক্সেছ কৰিছিল" + "%1$s%2$s পূৰ্বে আপোনাৰ মাইক্ৰ’ফ’ন এক্সেছ কৰিছিল" + "%1$s%2$s পূৰ্বে আপোনাৰ ফ’ন এক্সেছ কৰিছিল" + "%1$s%2$s পূৰ্বে আপোনাৰ ছেন্সৰসমূহ এক্সেছ কৰিছিল" + "%1$s%2$s পূৰ্বে আপোনাৰ এছএমএছ এক্সেছ কৰিছিল" + "%1$s%2$s পূৰ্বে আপোনাৰ ষ্ট’ৰেজ এক্সেছ কৰিছিল" + "%1$sএ আপোনাৰ %2$s এক্সেছ কৰা নাই" + "%1$sএ আপোনাৰ শাৰীৰিক কাৰ্যকলাপ এক্সেছ কৰা নাই" + "%1$sএ আপোনাৰ কেলেণ্ডাৰ এক্সেছ কৰা নাই" + "%1$sএ আপোনাৰ কল লগ এক্সেছ কৰা নাই" + "%1$sএ আপোনাৰ কেমেৰা এক্সেছ কৰা নাই" + "%1$sএ আপোনাৰ সম্পৰ্কসূচী এক্সেছ কৰা নাই" + "%1$sএ আপোনাৰ অৱস্থান এক্সেছ কৰা নাই" + "%1$sএ আপোনাৰ মাইক্ৰ’ফ’ন এক্সেছ কৰা নাই" + "%1$sএ আপোনাৰ ফ’ন এক্সেছ কৰা নাই" + "%1$sএ আপোনাৰ ছেন্সৰসমূহ এক্সেছ কৰা নাই" + "%1$sএ আপোনাৰ এছএমএছ এক্সেছ কৰা নাই" + "%1$sএ আপোনাৰ ষ্ট’ৰেজ এক্সেছ কৰা নাই" "এই অনুমতিটোৰ বাবে অন্তিমবাৰ এক্সেছ কৰা ডেটা বৰ্তমান নাই" "সকলো %1$s অনুমতি চাওক" "এই অনুমতি থকা সকলো এপ্ চাওক" diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml index 41551ec42..c4e7d646d 100644 --- a/res/values-az/strings.xml +++ b/res/values-az/strings.xml @@ -145,8 +145,30 @@ "İmtina edin" "%1$s üçün icazə" "Bu tətbiq üçün %1$s girişi" - "%1$s %2$s icazəsinə %3$s əvvəl daxil oldu" - "%1$s üçün %2$s icazəsi əlçatan deyil" + "%1$s %3$s əvvəl %2$s icazəsinə daxil oldu" + "%1$s %2$s əvvəl fiziki fəaliyyətinizə daxil oldu" + "%1$s %2$s əvvəl təqvimə daxil oldu" + "%1$s %2$s əvvəl zəng siyahısına daxil oldu" + "%1$s %2$s əvvəl kameraya daxil oldu" + "%1$s %2$s əvvəl kontaktlara daxil oldu" + "%1$s %2$s əvvəl məkana daxil oldu" + "%1$s %2$s əvvəl mikrofona daxil oldu" + "%1$s %2$s əvvəl telefona daxil oldu" + "%1$s %2$s əvvəl sensorlara daxil oldu" + "%1$s %2$s əvvəl SMS-ə daxil oldu" + "%1$s %2$s əvvəl yaddaşa daxil oldu" + "%1$s %2$s icazəsinə daxil olmayıb" + "%1$s fiziki fəaliyyətinizə daxil olmayıb" + "%1$s təqvimə daxil olmayıb" + "%1$s zəng siyahısına daxil olmayıb" + "%1$s kameraya daxil olmayıb" + "%1$s kontaktlara daxil olmayıb" + "%1$s məkana daxil olmayıb" + "%1$s mikrofona daxil olmayıb" + "%1$s telefona daxil olmayıb" + "%1$s sensorlara daxil olmayıb" + "%1$s SMS-ə daxil olmayıb" + "%1$s yaddaşa daxil olmayıb" "Son giriş datası hazırda bu icazə üçün əlçatan deyil" "Bütün %1$s icazələrinə baxın" "Bu icazəyə sahib olan bütün tətbiqlərə baxın" @@ -236,7 +258,7 @@ "%1$s defolt zəng yönləndirmə tətbiqi olaraq ayarlansın?" "İcazəyə ehtiyac yoxdur" "Defolt zəng edənin ID-si & spam tətbiqi" - "Zəng edənin ID-si & spam ətbiqi" + "Zəng ID-si & spam tətbiqi" "Gələn zəngləri müəyyən etməyə, spam və avtomatik zəngləri blok etməyə, lazımsız nömrələri qara siyahıya salmağa və daha çoxuna icazə verən tətbiqlər" "%1$s defolt zəng edənin ID-si və spam tətbiqi olaraq ayarlansın?" "İcazəyə ehtiyac yoxdur" diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml index e2df96b5b..9c33836ab 100644 --- a/res/values-b+sr+Latn/strings.xml +++ b/res/values-b+sr+Latn/strings.xml @@ -148,8 +148,30 @@ "Odbij" "%1$s - dozvola" "Pristup ove aplikacije funkciji „%1$s“" - "Aplikacija %1$s je pristupila funkciji „%2$s“ pre %3$s" - "Aplikacija %1$s nije pristupila funkciji „%2$s“" + "Aplikacija %1$s je pristupila funkciji „%2$s“ pre %3$s" + "Aplikacija %1$s je pristupila fizičkim aktivnostima pre %2$s" + "Aplikacija %1$s je pristupila kalendaru pre %2$s" + "Aplikacija %1$s je pristupila evidencijama poziva pre %2$s" + "Aplikacija %1$s je pristupila kameri pre %2$s" + "Aplikacija je %1$s pristupila kontaktima pre %2$s" + "Aplikacija %1$s je pristupila lokaciji pre %2$s" + "Aplikacija %1$s je pristupila mikrofonu pre %2$s" + "Aplikacija %1$s je pristupila telefonu pre %2$s" + "Aplikacija %1$s je pristupila senzorima pre %2$s" + "Aplikacija je %1$s je pristupila SMS-ovima pre %2$s" + "Aplikacija %1$s je pristupila memorijskom prostoru pre %2$s" + "Aplikacija %1$s nije pristupila funkciji „%2$s“" + "Aplikacija %1$s nije pristupila fizičkim aktivnostima" + "Aplikacija %1$s nije pristupila kalendaru" + "Aplikacija %1$s nije pristupila evidencijama poziva" + "Aplikacija %1$s nije pristupila kameri" + "Aplikacija %1$s nije pristupila kontaktima" + "Aplikacija %1$s nije pristupila lokaciji" + "Aplikacija %1$snije pristupila mikrofonu" + "Aplikacija %1$s nije pristupila telefonu" + "Aplikacija %1$s nije pristupila senzorima" + "Aplikacija %1$s nije pristupila SMS-ovima" + "Aplikacija %1$s nije pristupila memorijskom prostoru" "Podaci o poslednjem pristupu trenutno nisu dostupni za ovu dozvolu" "Prikaži sve dozvole (%1$s)" "Prikaži sve aplikacije sa ovom dozvolom" diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml index dd9528014..95d3e06f1 100644 --- a/res/values-be/strings.xml +++ b/res/values-be/strings.xml @@ -151,8 +151,30 @@ "Адмовіць" "Дазвол \"%1$s\"" "%1$s: доступ для гэтай праграмы" - "Праграма \"%1$s\" атрымала доступ да функцыі \"%2$s\" %3$s таму назад" - "Праграма \"%1$s\" не атрымала доступу да функцыі \"%2$s\"" + "Праграма \"%1$s\" атрымала доступ да дазволу \"%2$s\" %3$s таму назад" + "Праграма \"%1$s\" атрымала доступ да фізічнай актыўнасці %2$s таму" + "Праграма \"%1$s\" атрымала доступ да календара %2$s таму назад" + "Праграма \"%1$s\" атрымала доступ да журналаў выклікаў %2$s таму назад" + "Праграма \"%1$s\" атрымала доступ да камеры %2$s таму" + "Праграма \"%1$s\" атрымала доступ да кантактаў %2$s таму назад" + "Праграма \"%1$s\" атрымала доступ да даных месцазнаходжання %2$s таму" + "Праграма \"%1$s\" атрымала доступ да мікрафона %2$s таму назад" + "Праграма \"%1$s\" атрымала доступ да тэлефона %2$s таму назад" + "Праграма \"%1$s\" атрымала доступ да датчыкаў %2$s таму назад" + "Праграма \"%1$s\" атрымала доступ да SMS %2$s таму назад" + "Праграма \"%1$s\" атрымала доступ да сховішча %2$s таму назад" + "Праграма \"%1$s\" не атрымала доступу да дазволу \"%2$s\"" + "Праграма \"%1$s\" не атрымала доступу да даных фізічнай актыўнасці" + "Праграма \"%1$s\" не атрымала доступу да календара" + "Праграма \"%1$s\" не атрымала доступу да журналаў выклікаў" + "Праграма \"%1$s\" не атрымала доступу да камеры" + "Праграма \"%1$s\" не атрымала доступу да кантактаў" + "Праграма \"%1$s\" не атрымала доступу да даных месцазнаходжання" + "Праграма \"%1$s\" не атрымала доступу да мікрафона" + "Праграма \"%1$s\" не атрымала доступу да тэлефона" + "Праграма \"%1$s\" не атрымала доступу да датчыкаў" + "Праграма \"%1$s\" не атрымала доступу да SMS" + "Праграма \"%1$s\" не атрымала доступу да сховішча" "Даныя пра апошні доступ цяпер недаступныя для гэтага дазволу" "Паказаць усе дазволы праграмы \"%1$s\"" "Паказаць усе праграмы з гэтым дазволам" diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml index 4160bbd68..2dc45da87 100644 --- a/res/values-bg/strings.xml +++ b/res/values-bg/strings.xml @@ -145,8 +145,30 @@ "Отказ" "Разрешение за %1$s" "Достъп до %1$s за това приложение" - "%1$s осъществи достъп до %2$s преди %3$s" - "Приложението %1$s не е осъществило достъп до %2$s" + "%1$s осъществи достъп до %2$s преди %3$s" + "%1$s осъществи достъп до физическата ви активност преди %2$s" + "%1$s осъществи достъп до календара ви преди %2$s" + "%1$s осъществи достъп до списъка ви с обажданията преди %2$s" + "%1$s осъществи достъп до камерата ви преди %2$s" + "%1$s осъществи достъп до контактите ви преди %2$s" + "%1$s осъществи достъп до местоположението ви преди %2$s" + "%1$s осъществи достъп до микрофона ви преди %2$s" + "%1$s осъществи достъп до телефона ви преди %2$s" + "%1$s осъществи достъп до сензорите ви преди %2$s" + "%1$s осъществи достъп до SMS съобщенията ви преди %2$s" + "%1$s осъществи достъп до хранилището ви преди %2$s" + "Приложението %1$s не е осъществило достъп до %2$s" + "Прилож. %1$s не е осъществило достъп до физическата ви активност" + "Приложението %1$s не е осъществило достъп до календара ви" + "Прилож. %1$s не е осъществило достъп до списъка ви с обажданията" + "Приложението %1$s не е осъществило достъп до камерата ви" + "Приложението %1$s не е осъществило достъп до контактите ви" + "Приложението %1$s не е осъществило достъп до местоположението ви" + "Приложението %1$s не е осъществило достъп до микрофона ви" + "Приложението %1$s не е осъществило достъп до телефона ви" + "Приложението %1$s не е осъществило достъп до сензорите ви" + "Приложението %1$s не е осъществило достъп до SMS съобщенията ви" + "Приложението %1$s не е осъществило достъп до хранилището ви" "Данните за последния достъп понастоящем не са налице за това разрешение" "Преглед на всички разрешения за %1$s" "Преглед на всички приложения с това разрешение" diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml index 2348b97a5..4c14371f7 100644 --- a/res/values-bn/strings.xml +++ b/res/values-bn/strings.xml @@ -123,7 +123,7 @@ "এই অনুযায়ী ফিল্টার করা হয়েছে: %1$s" "সবকিছু ড্যাশবোর্ডে দেখুন" "এই অনুযায়ী ফিল্টার করুন" - "অনুমতির মাধ্যমে ফিল্টার করুন" + "অনুমতি অনুযায়ী ফিল্টার করুন" "সময় অনুযায়ী ফিল্টার করুন" "বেশি ব্যবহার করা অনুমতি" "সবচেয়ে বেশি অ্যাক্সেস করা" @@ -145,8 +145,30 @@ "খারিজ করুন" "%1$s অনুমতি" "এই অ্যাপের জন্য %1$s অ্যাক্সেস" - "%3$s আগে %1$s আপনার %2$s অ্যাক্সেস করেছে" - "%1$s আপনার %2$s অ্যাক্সেস করেনি" + "%3$s আগে %1$s আপনার %2$s অ্যাক্সেস করেছে" + "%2$s আগে %1$s আপনার শারীরিক অ্যাক্টিভিটির তথ্য অ্যাক্সেস করেছে" + "%2$s আগে %1$s আপনার ক্যালেন্ডার অ্যাক্সেস করেছে" + "%2$s আগে %1$s আপনার কল লগ অ্যাক্সেস করেছে" + "%2$s আগে %1$s আপনার ক্যামেরা অ্যাক্সেস করেছে" + "%2$s আগে %1$s আপনার পরিচিতি অ্যাক্সেস করেছে" + "%2$s আগে %1$s আপনার লোকেশন অ্যাক্সেস করেছে" + "%2$s আগে %1$s আপনার মাইক্রোফোন অ্যাক্সেস করেছে" + "%2$s আগে %1$s আপনার ফোন অ্যাক্সেস করেছে" + "%2$s আগে %1$s আপনার সেন্সর অ্যাক্সেস করেছে" + "%2$s আগে %1$s আপনার এসএমএস অ্যাক্সেস করেছে" + "%2$s আগে %1$s আপনার স্টোরেজ অ্যাক্সেস করেছে" + "%1$s আপনার %2$s অ্যাক্সেস করেনি" + "%1$s আপনার শারীরিক অ্যাক্টিভিটির তথ্য অ্যাক্সেস করেনি" + "%1$s আপনার ক্যালেন্ডার অ্যাক্সেস করেনি" + "%1$s আপনার কল লগ অ্যাক্সেস করেনি" + "%1$s আপনার ক্যামেরা অ্যাক্সেস করেনি" + "%1$s আপনার পরিচিতি অ্যাক্সেস করেনি" + "%1$s আপনার লোকেশন অ্যাক্সেস করেনি" + "%1$s আপনার মাইক্রোফোন অ্যাক্সেস করেনি" + "%1$s আপনার ফোন অ্যাক্সেস করেনি" + "%1$s আপনার সেন্সর অ্যাক্সেস করেনি" + "%1$s আপনার এসএমএস অ্যাক্সেস করেনি" + "%1$s আপনার স্টোরেজ অ্যাক্সেস করেনি" "এই অনুমতির জন্য শেষবারের অ্যাক্সেস করা ডেটা বর্তমানে উপলভ্য নয়" "%1$s-কে দেওয়া সব অনুমতি দেখুন" "যেসব অ্যাপের এই অনুমতি আছে সেগুলি দেখুন" @@ -275,7 +297,7 @@ "অনুমতি দেবেন না" "উন্নত সেটিংস" "উন্নত সেটিংস" - "ব্যবহার করা সিস্টেম অ্যাপ দেখুন" + "সিস্টেম অ্যাপের ব্যবহার দেখুন" "স্ট্যাটাস বার, ড্যাশবোর্ড ও অন্য জায়গায় সিস্টেম অ্যাপ ব্যবহারের অনুমতি সংক্রান্ত বিজ্ঞপ্তি দেখায়" "নিচে উল্লেখ করা তালিকা থেকে চালু অ্যাপগুলি দেখুন" "অ্যাসিস্ট্যান্টের ট্রিগার সংক্রান্ত শনাক্তকরণ দেখায়" diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml index 9cf06893e..197a1846c 100644 --- a/res/values-bs/strings.xml +++ b/res/values-bs/strings.xml @@ -148,8 +148,30 @@ "Odbij" "Odobrenje %1$s" "Pristup \"%1$s\" za ovu aplikaciju" - "Aplikacija %1$s je pristupila odobrenju \"%2$s\" prije %3$s" - "Aplikacija %1$s nije pristupila vašem odobrenju \"%2$s\"" + "Aplikacija %1$s pristupila je odobrenju %2$s prije %3$s" + "Aplikacija %1$s pristupila je vašoj fizičkoj aktivnosti prije %2$s" + "Aplikacija %1$s pristupila je vašem kalendaru prije %2$s" + "Aplikacija %1$s pristupila je vašim popisima poziva prije %2$s" + "Aplikacija %1$s pristupila je vašoj kameri prije %2$s" + "Aplikacija %1$s pristupila je vašem sadržaju prije %2$s" + "Aplikacija %1$s pristupila je vašoj lokaciji prije %2$s" + "Aplikacija %1$s pristupila je vašem mikrofonu prije %2$s" + "Aplikacija %1$s pristupila je vašem telefonu prije %2$s" + "Aplikacija %1$s pristupila je vašim senzorima prije %2$s" + "Aplikacija %1$s pristupila je vašem SMS-u prije %2$s" + "Aplikacija %1$s pristupila je vašoj pohrani prije %2$s" + "Aplikacija %1$s nije pristupila vašem odobrenju %2$s" + "Aplikacija %1$s nije pristupila vašim fizičkim aktivnostima" + "Aplikacija %1$s nije pristupila vašem kalendaru" + "Aplikacija %1$s nije pristupila vašim popisima poziva" + "Aplikacija %1$s nije pristupila vašoj kameri" + "Aplikacija %1$s nije pristupila vašim kontaktima" + "Aplikacija %1$s nije pristupila vašoj lokaciji" + "Aplikacija %1$s nije pristupila vašem mikrofonu" + "Aplikacija %1$s nije pristupila vašem telefonu" + "Aplikacija %1$s nije pristupila vašim senzorima" + "Aplikacija %1$s nije pristupila vašem SMS-u" + "Aplikacija %1$s nije pristupila vašoj pohrani" "Zadnji pristup podacima trenutno nije dostupan za ovo odobrenje" "Prikaži sva odobrenja aplikacije %1$s" "Prikaži sve aplikacije koje imaju ovo odobrenje" diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml index 764b2c972..5f5ba0ba8 100644 --- a/res/values-ca/strings.xml +++ b/res/values-ca/strings.xml @@ -145,8 +145,30 @@ "Denega" "Permís per accedir a %1$s" "Accés a %1$s per a aquesta aplicació" - "%1$s ha accedit a %2$s fa %3$s" - "%1$s no ha accedit a %2$s" + "%1$s ha accedit fa %3$s a: %2$s" + "%1$s ha accedit a l\'activitat física fa %2$s" + "%1$s ha accedit al calendari fa %2$s" + "%1$s ha accedit als registres de trucades fa %2$s" + "%1$s ha accedit a la càmera fa %2$s" + "%1$s ha accedit als contactes fa %2$s" + "%1$s ha accedit a la ubicació fa %2$s" + "%1$s ha accedit al micròfon fa %2$s" + "%1$s ha accedit al telèfon fa %2$s" + "%1$s ha accedit als sensors fa %2$s" + "%1$s ha accedit als SMS fa %2$s" + "%1$s ha accedit a l\'emmagatzematge fa %2$s" + "%1$s no ha accedit a: %2$s" + "%1$s no ha accedit a l\'activitat física" + "%1$s no ha accedit al calendari" + "%1$s no ha accedit als registres de trucades" + "%1$s no ha accedit a la càmera" + "%1$s no ha accedit als contactes" + "%1$s no ha accedit a la ubicació" + "%1$s no ha accedit al micròfon" + "%1$s no ha accedit al telèfon" + "%1$s no ha accedit als sensors" + "%1$s no ha accedit als SMS" + "%1$s no ha accedit a l\'emmagatzematge" "Actualment, les dades d\'accés més recents d\'aquest permís no estan disponibles" "Mostra tots els permisos de: %1$s" "Mostra totes les aplicacions amb aquest permís" diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml index 200b41d04..ceaddea27 100644 --- a/res/values-cs/strings.xml +++ b/res/values-cs/strings.xml @@ -151,8 +151,30 @@ "Zakázat" "Oprávnění %1$s" "Přístup aplikace: %1$s" - "Aplikace %1$s získala přístup k těmto údajům (před: %3$s): %2$s" - "Aplikace %1$s nezískala přístup k oprávnění %2$s" + "Aplikace %1$s před %3$s získala přístup k oprávnění %2$s" + "Aplikace %1$s před %2$s získala přístup k vaší fyzické aktivitě" + "Aplikace %1$s před %2$s získala přístup ke kalendáři" + "Aplikace %1$s před %2$s získala přístup k seznamu hovorů" + "Aplikace %1$s před %2$s získala přístup k fotoaparátu" + "Aplikace %1$s před %2$s získala přístup ke kontaktům" + "Aplikace %1$s před %2$s získala přístup k poloze" + "Aplikace %1$s před %2$s nezískala přístup k mikrofonu" + "Aplikace %1$s před %2$s získala přístup k telefonu" + "Aplikace %1$s před %2$s získala přístup k senzorům" + "Aplikace %1$s před %2$s získala přístup k SMS" + "Aplikace %1$s před %2$s získala přístup k úložišti" + "Aplikace %1$s nezískala přístup k oprávnění %2$s" + "Aplikace %1$s nezískala přístup k vaší fyzické aktivitě" + "Aplikace %1$s nezískala přístup ke kalendáři" + "Aplikace %1$s nezískala přístup k seznamu hovorů" + "Aplikace %1$s nezískala přístup k fotoaparátu" + "Aplikace %1$s nezískala přístup ke kontaktům" + "Aplikace %1$s nezískala přístup k poloze" + "Aplikace %1$s nezískala přístup k mikrofonu" + "Aplikace %1$s nezískala přístup k telefonu" + "Aplikace %1$s nezískala přístup k senzorům" + "Aplikace %1$s nezískala přístup k SMS" + "Aplikace %1$s nezískala přístup k úložišti" "Údaje o posledním přístupu momentálně nejsou v rámci tohoto oprávnění dostupné" "Zobrazit všechna oprávnění aplikace %1$s" "Zobrazit všechny aplikace s tímto oprávněním" @@ -226,7 +248,7 @@ "Není potřeba žádné oprávnění" "Výchozí aplikace telefonu" "Aplikace k telefonování" - "Aplikace, které vám v zařízení umožňují realizovat a přijímat hovory" + "Aplikace, které vám v zařízení umožňují volat a přijímat hovory" "Nastavit %1$s jako výchozí aplikaci k telefonování?" "Získá přístup k seznamu hovorů a posílání SMS" "Výchozí aplikace pro SMS" diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml index ca63c0af9..4b4cadedc 100644 --- a/res/values-da/strings.xml +++ b/res/values-da/strings.xml @@ -145,8 +145,30 @@ "Afvis" "Tilladelse til %1$s" "Adgang til %1$s for denne app" - "%1$s fik adgang til %2$s for %3$s siden" - "%1$s har ikke haft adgang til %2$s" + "%1$s havde adgang til %2$s for %3$s siden" + "%1$s havde adgang til din fysiske aktivitet for %2$s siden" + "%1$s havde adgang til din kalender for %2$s siden" + "%1$s havde adgang til dine opkaldslister for %2$s siden" + "%1$s havde adgang til dit kamera for %2$s siden" + "%1$s havde adgang til dine kontakter for %2$s siden" + "%1$s havde adgang til din placering for %2$s siden" + "%1$s havde adgang til din mikrofon for %2$s siden" + "%1$s havde adgang til din telefon for %2$s siden" + "%1$s havde adgang til dine sensorer for %2$s siden" + "%1$s havde adgang til din sms for %2$s siden" + "%1$s havde adgang til din lagerplads for %2$s siden" + "%1$s har ikke haft adgang til %2$s" + "%1$s har ikke haft adgang til din fysiske aktivitet" + "%1$s har ikke haft adgang til din kalender" + "%1$s har ikke haft adgang til dine opkaldslister" + "%1$s har ikke haft adgang til dit kamera" + "%1$s har ikke haft adgang til dine kontakter" + "%1$s har ikke haft adgang til din placering" + "%1$s har ikke haft adgang til din mikrofon" + "%1$s har ikke haft adgang til din telefon" + "%1$s har ikke haft adgang til dine sensorer" + "%1$s har ikke haft adgang til din sms" + "%1$s har ikke haft adgang til din lagerplads" "De seneste adgangsdata er ikke tilgængelige for denne tilladelse i øjeblikket" "Se alle tilladelser for %1$s" "Se alle apps med denne tilladelse" diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index d150fb531..8e92f4f98 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -122,7 +122,7 @@ "Alle im Dashboard aufrufen" "Gefiltert nach: %1$s" "Alle Nutzungen im Dashboard ansehen" - "Filtern nach" + "Filterkriterium" "Nach Berechtigungen filtern" "Nach Zeitraum filtern" "Meiste Berechtigungen" @@ -145,8 +145,30 @@ "Ablehnen" "Berechtigung \"%1$s\"" "\"%1$s\"-Zugriff für diese App" - "%1$s hat vor %3$s die Berechtigung \"%2$s\" genutzt" - "%1$s hat nicht die Berechtigung \"%2$s\" genutzt" + "%1$s hat vor %3$s die Berechtigung \"%2$s\" genutzt" + "%1$s hat vor %2$s auf deine körperliche Aktivität zugegriffen" + "%1$s hat vor %2$s auf deinen Kalender zugegriffen" + "%1$s hat vor %2$s auf deine Anrufliste zugegriffen" + "%1$s hat vor %2$s auf deine Kamera zugegriffen" + "%1$s hat vor %2$s auf deine Kontakte zugegriffen" + "%1$s hat vor %2$s auf deinen Standort zugegriffen" + "%1$s hat vor %2$s auf dein Mikrofon zugegriffen" + "%1$s hat vor %2$s auf dein Smartphone zugegriffen" + "%1$s hat vor %2$s auf deine Sensoren zugegriffen" + "%1$s hat vor %2$s auf deine SMS zugegriffen" + "%1$s hat vor %2$s auf deinen Speicher zugegriffen" + "%1$s hat nicht die Berechtigung \"%2$s\" genutzt" + "%1$s hat nicht auf deine körperliche Aktivität zugegriffen" + "%1$s hat nicht auf deinen Kalender zugegriffen" + "%1$s hat nicht auf deine Anrufliste zugegriffen" + "%1$s hat nicht auf deine Kamera zugegriffen" + "%1$s hat nicht auf deine Kontakte zugegriffen" + "%1$s hat nicht auf deinen Standort zugegriffen" + "%1$s hat nicht auf dein Mikrofon zugegriffen" + "%1$s hat nicht auf dein Smartphone zugegriffen" + "%1$s hat nicht auf deine Sensoren zugegriffen" + "%1$s hat nicht auf deine SMS zugegriffen" + "%1$s hat nicht auf deinen Speicher zugegriffen" "Daten zum letzten Zugriff sind derzeit nicht für diese Berechtigung verfügbar" "Alle %1$s-Berechtigungen anzeigen" "Alle Apps mit dieser Berechtigung anzeigen" diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml index e01b644fd..48f0bdecc 100644 --- a/res/values-el/strings.xml +++ b/res/values-el/strings.xml @@ -145,8 +145,30 @@ "Να μην επιτρέπεται" "Άδεια %1$s" "Πρόσβαση σε %1$s για αυτήν την εφαρμογή" - "Η εφαρμογή %1$s είχε πρόσβαση σε %2$s πριν από %3$s" - "Η εφαρμογή %1$s δεν απέκτησε πρόσβαση σε %2$s" + "Η εφαρμογή %1$s απέκτησε πρόσβαση στην άδεια %2$s πριν από %3$s" + "Η εφαρμογή %1$s απέκτησε πρόσβ. στη σωματική δραστηρ. πριν από %2$s" + "Η εφαρμογή %1$s απέκτησε πρόσβαση στο ημερολόγιό σας πριν από %2$s" + "Η εφαρμ. %1$s απέκτησε πρόσβ. στα αρχεία καταγρ. κλήσ. πριν από %2$s" + "Η εφαρμογή %1$s απέκτησε πρόσβαση στην κάμερά σας πριν από %2$s" + "Η εφαρμογή %1$s απέκτησε πρόσβαση στις επαφές σας πριν από %2$s" + "Η εφαρμογή %1$s απέκτησε πρόσβαση στην τοποθεσία σας πριν από %2$s" + "Η εφαρμογή %1$s απέκτησε πρόσβαση στο μικρόφωνό σας πριν από %2$s" + "Η εφαρμογή %1$s απέκτησε πρόσβαση στο τηλέφωνό σας πριν από %2$s" + "Η εφαρμογή %1$s απέκτησε πρόσβαση στους αισθητήρες σας πριν από %2$s" + "Η εφαρμογή %1$s απέκτησε πρόσβαση στα SMS σας πριν από %2$s" + "Η εφαρμογή %1$s απέκτησε πρόσβαση στον αποθηκευτ. χώρο πριν από %2$s" + "Η εφαρμογή %1$s δεν απέκτησε πρόσβαση στην άδεια %2$s" + "Η εφαρμογή %1$s δεν απέκτησε πρόσβαση στη σωματική δραστηριότητα" + "Η εφαρμογή %1$s δεν απέκτησε πρόσβαση στο ημερολόγιό σας" + "Η εφαρμογή %1$s δεν απέκτησε πρόσβαση στα αρχεία καταγρ. κλήσεων" + "Η εφαρμογή %1$s δεν απέκτησε πρόσβαση στην κάμερά σας" + "Η εφαρμογή %1$s δεν απέκτησε πρόσβαση στις επαφές σας" + "Η εφαρμογή %1$s δεν απέκτησε πρόσβαση στην τοποθεσία σας" + "Η εφαρμογή %1$s δεν απέκτησε πρόσβαση στο μικρόφωνό σας" + "Η εφαρμογή %1$s δεν απέκτησε πρόσβαση στο τηλέφωνό σας" + "Η εφαρμογή %1$s δεν απέκτησε πρόσβαση στους αισθητήρες σας" + "Η εφαρμογή %1$s δεν απέκτησε πρόσβαση στα SMS σας" + "Η εφαρμογή %1$s δεν απέκτησε πρόσβαση στον αποθηκευτικό χώρο σας" "Τα δεδομένα τελευταίας πρόσβασης δεν είναι διαθέσιμα αυτήν τη στιγμή για αυτήν την άδεια" "Εμφάνιση όλων των αδειών της εφαρμογής %1$s" "Εμφάνιση όλων των εφαρμογών με αυτήν την άδεια" diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml index 94929e994..5a7758312 100644 --- a/res/values-en-rAU/strings.xml +++ b/res/values-en-rAU/strings.xml @@ -145,8 +145,30 @@ "Deny" "%1$s permission" "%1$s access for this app" - "%1$s accessed your %2$s %3$s ago" - "%1$s has not accessed your %2$s" + "%1$s accessed your %2$s %3$s ago" + "%1$s accessed your physical activity %2$s ago" + "%1$s accessed your calendar %2$s ago" + "%1$s accessed your call logs %2$s ago" + "%1$s accessed your camera %2$s ago" + "%1$s accessed your contacts %2$s ago" + "%1$s accessed your location %2$s ago" + "%1$s accessed your microphone %2$s ago" + "%1$s accessed your phone %2$s ago" + "%1$s accessed your sensors %2$s ago" + "%1$s accessed your SMS %2$s ago" + "%1$s accessed your storage %2$s ago" + "%1$s has not accessed your %2$s" + "%1$s has not accessed your physical activity" + "%1$s has not accessed your calendar" + "%1$s has not accessed your call logs" + "%1$s has not accessed your camera" + "%1$s has not accessed your contacts" + "%1$s has not accessed your location" + "%1$s has not accessed your microphone" + "%1$s has not accessed your phone" + "%1$s has not accessed your sensors" + "%1$s has not accessed your SMS" + "%1$s has not accessed your storage" "Last access data is currently not available for this permission" "See all %1$s permissions" "See all apps with this permission" diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml index 94929e994..5a7758312 100644 --- a/res/values-en-rCA/strings.xml +++ b/res/values-en-rCA/strings.xml @@ -145,8 +145,30 @@ "Deny" "%1$s permission" "%1$s access for this app" - "%1$s accessed your %2$s %3$s ago" - "%1$s has not accessed your %2$s" + "%1$s accessed your %2$s %3$s ago" + "%1$s accessed your physical activity %2$s ago" + "%1$s accessed your calendar %2$s ago" + "%1$s accessed your call logs %2$s ago" + "%1$s accessed your camera %2$s ago" + "%1$s accessed your contacts %2$s ago" + "%1$s accessed your location %2$s ago" + "%1$s accessed your microphone %2$s ago" + "%1$s accessed your phone %2$s ago" + "%1$s accessed your sensors %2$s ago" + "%1$s accessed your SMS %2$s ago" + "%1$s accessed your storage %2$s ago" + "%1$s has not accessed your %2$s" + "%1$s has not accessed your physical activity" + "%1$s has not accessed your calendar" + "%1$s has not accessed your call logs" + "%1$s has not accessed your camera" + "%1$s has not accessed your contacts" + "%1$s has not accessed your location" + "%1$s has not accessed your microphone" + "%1$s has not accessed your phone" + "%1$s has not accessed your sensors" + "%1$s has not accessed your SMS" + "%1$s has not accessed your storage" "Last access data is currently not available for this permission" "See all %1$s permissions" "See all apps with this permission" diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml index 94929e994..5a7758312 100644 --- a/res/values-en-rGB/strings.xml +++ b/res/values-en-rGB/strings.xml @@ -145,8 +145,30 @@ "Deny" "%1$s permission" "%1$s access for this app" - "%1$s accessed your %2$s %3$s ago" - "%1$s has not accessed your %2$s" + "%1$s accessed your %2$s %3$s ago" + "%1$s accessed your physical activity %2$s ago" + "%1$s accessed your calendar %2$s ago" + "%1$s accessed your call logs %2$s ago" + "%1$s accessed your camera %2$s ago" + "%1$s accessed your contacts %2$s ago" + "%1$s accessed your location %2$s ago" + "%1$s accessed your microphone %2$s ago" + "%1$s accessed your phone %2$s ago" + "%1$s accessed your sensors %2$s ago" + "%1$s accessed your SMS %2$s ago" + "%1$s accessed your storage %2$s ago" + "%1$s has not accessed your %2$s" + "%1$s has not accessed your physical activity" + "%1$s has not accessed your calendar" + "%1$s has not accessed your call logs" + "%1$s has not accessed your camera" + "%1$s has not accessed your contacts" + "%1$s has not accessed your location" + "%1$s has not accessed your microphone" + "%1$s has not accessed your phone" + "%1$s has not accessed your sensors" + "%1$s has not accessed your SMS" + "%1$s has not accessed your storage" "Last access data is currently not available for this permission" "See all %1$s permissions" "See all apps with this permission" diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml index 94929e994..5a7758312 100644 --- a/res/values-en-rIN/strings.xml +++ b/res/values-en-rIN/strings.xml @@ -145,8 +145,30 @@ "Deny" "%1$s permission" "%1$s access for this app" - "%1$s accessed your %2$s %3$s ago" - "%1$s has not accessed your %2$s" + "%1$s accessed your %2$s %3$s ago" + "%1$s accessed your physical activity %2$s ago" + "%1$s accessed your calendar %2$s ago" + "%1$s accessed your call logs %2$s ago" + "%1$s accessed your camera %2$s ago" + "%1$s accessed your contacts %2$s ago" + "%1$s accessed your location %2$s ago" + "%1$s accessed your microphone %2$s ago" + "%1$s accessed your phone %2$s ago" + "%1$s accessed your sensors %2$s ago" + "%1$s accessed your SMS %2$s ago" + "%1$s accessed your storage %2$s ago" + "%1$s has not accessed your %2$s" + "%1$s has not accessed your physical activity" + "%1$s has not accessed your calendar" + "%1$s has not accessed your call logs" + "%1$s has not accessed your camera" + "%1$s has not accessed your contacts" + "%1$s has not accessed your location" + "%1$s has not accessed your microphone" + "%1$s has not accessed your phone" + "%1$s has not accessed your sensors" + "%1$s has not accessed your SMS" + "%1$s has not accessed your storage" "Last access data is currently not available for this permission" "See all %1$s permissions" "See all apps with this permission" diff --git a/res/values-en-rXC/strings.xml b/res/values-en-rXC/strings.xml index a0651b1cf..966c154aa 100644 --- a/res/values-en-rXC/strings.xml +++ b/res/values-en-rXC/strings.xml @@ -145,8 +145,30 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‎‏‎‏‎‎‏‎‎‏‏‏‏‎‏‎‏‏‏‏‏‎‏‎‏‎‎‎‏‎‏‎‏‏‎‎‏‏‎‏‎‏‎‏‎‎‎‏‎‎‏‎‎‎‎Deny‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‎‎‎‎‏‎‏‎‏‏‎‎‏‏‏‎‏‎‎‎‏‏‎‎‏‎‏‎‏‏‏‎‎‎‏‎‎‏‎‎‏‏‏‎‎‎‎‏‏‏‏‎‎‎‎‏‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ permission‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‎‎‏‎‏‏‎‏‎‏‏‏‏‎‏‎‏‎‏‎‎‏‎‏‏‎‎‏‎‏‎‏‎‏‎‏‏‏‏‏‎‏‎‏‎‎‎‎‏‏‏‎‏‎‎‎‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ access for this app‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‏‎‏‏‎‏‏‎‎‎‎‏‏‏‎‎‏‎‏‎‏‏‏‏‎‎‏‏‏‎‎‎‏‎‎‎‎‏‎‏‎‏‎‏‏‎‏‏‏‎‎‏‎‎‎‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ accessed your ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎ ‎‏‎‎‏‏‎%3$s‎‏‎‎‏‏‏‎ ago‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‏‎‏‎‏‏‎‏‏‎‎‏‎‏‏‎‏‎‏‏‏‎‏‎‎‏‎‎‎‏‎‎‏‏‎‏‎‎‏‎‎‏‏‏‏‎‏‏‎‏‎‎‎‎‎‏‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ has not accessed your ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‏‎‎‏‏‎‏‎‎‎‎‎‏‏‏‏‎‏‏‎‏‏‏‏‎‎‏‎‏‏‏‎‎‎‏‎‏‎‏‏‏‎‎‏‎‏‏‏‏‎‎‏‎‏‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ accessed your ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎ ‎‏‎‎‏‏‎%3$s‎‏‎‎‏‏‏‎ ago‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‎‎‏‏‏‎‏‏‏‎‎‏‎‏‏‎‏‎‏‎‎‎‏‏‏‎‏‏‏‎‎‏‎‎‎‎‎‎‏‎‏‎‏‏‎‏‎‎‎‏‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ accessed your physical activity ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎ ago‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‏‏‏‏‏‎‏‏‏‏‏‎‎‎‏‏‏‏‎‎‏‏‎‎‎‏‎‏‎‏‎‏‎‎‏‎‎‏‎‏‏‏‏‏‏‏‎‏‎‎‏‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ accessed your calendar ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎ ago‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‎‎‏‎‎‎‎‎‎‏‎‎‎‎‏‏‎‏‏‎‎‎‎‏‏‎‎‏‎‎‎‏‏‏‏‏‏‏‎‎‏‏‏‏‏‎‎‏‏‏‏‎‏‎‎‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ accessed your call logs ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎ ago‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‎‎‎‏‏‎‏‎‏‏‏‏‏‎‎‎‎‏‏‏‏‎‏‏‎‏‎‏‎‎‏‎‏‏‎‎‏‎‎‎‏‏‎‎‎‎‎‏‏‎‎‎‏‏‎‎‏‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ accessed your camera ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎ ago‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‏‎‎‏‏‎‎‎‎‏‏‎‎‏‎‏‏‎‏‏‏‏‎‎‏‏‎‎‏‏‏‏‏‎‎‏‏‏‏‏‎‏‏‏‏‎‎‎‎‏‏‏‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ accessed your contacts ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎ ago‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‏‎‎‏‎‎‏‎‎‎‏‏‎‎‎‎‎‏‏‎‏‎‎‏‎‎‏‏‏‏‎‎‎‎‎‏‏‏‎‎‎‏‏‏‎‎‏‎‎‎‎‎‎‎‏‏‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ accessed your location ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎ ago‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‎‏‎‏‎‏‏‏‎‏‏‎‏‏‎‎‏‎‎‎‎‏‏‏‏‎‎‎‎‏‏‎‎‎‏‏‏‏‎‎‏‏‏‏‏‎‎‎‎‏‎‏‎‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ accessed your microphone ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎ ago‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‏‏‎‏‏‏‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‏‎‎‎‎‏‎‏‎‏‏‏‏‎‎‎‎‎‏‎‏‏‏‎‎‎‏‎‎‎‎‏‎‏‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ accessed your phone ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎ ago‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‏‎‏‎‎‏‎‏‏‏‎‏‎‎‎‎‎‎‎‏‎‏‏‎‏‎‎‎‎‎‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‎‎‏‏‎‏‎‎‎‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ accessed your sensors ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎ ago‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‏‎‏‏‎‎‎‎‎‎‎‏‎‎‏‏‏‏‏‎‎‏‏‎‎‎‎‎‏‏‏‏‎‎‎‏‏‎‏‎‏‏‏‎‎‏‎‎‎‏‏‎‏‎‏‏‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ accessed your SMS ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎ ago‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‏‎‎‏‏‏‎‏‏‎‏‎‎‎‎‎‏‎‏‏‎‏‎‎‏‏‏‎‏‎‏‏‎‎‏‎‏‏‏‏‎‎‏‏‏‏‎‎‎‏‏‏‎‎‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ accessed your storage ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎ ago‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‏‏‎‎‎‏‏‏‏‏‏‎‎‏‏‏‎‏‎‏‏‏‏‏‎‏‏‏‏‎‎‏‎‎‏‎‎‎‎‎‎‏‏‎‏‎‎‏‏‎‎‎‏‏‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ has not accessed your ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‎‎‏‏‎‎‏‎‏‎‎‎‎‏‎‏‎‏‎‎‎‎‎‏‎‏‎‏‏‎‏‎‏‎‏‏‎‎‏‏‎‏‎‎‏‏‎‎‎‏‏‎‏‎‏‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ has not accessed your physical activity‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‎‎‎‏‏‎‏‎‎‎‏‏‎‎‎‎‏‎‎‏‏‏‏‎‎‎‏‏‎‎‏‏‏‏‎‎‎‏‏‎‏‎‎‏‎‏‎‎‎‎‏‏‎‏‎‎‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ has not accessed your calendar‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‏‎‎‏‏‏‎‎‎‎‏‏‏‎‏‏‏‏‎‎‎‎‏‏‎‏‏‏‎‎‎‏‏‎‎‏‎‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‎‏‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ has not accessed your call logs‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‏‏‏‎‏‎‎‎‎‏‏‏‎‎‏‏‎‏‏‏‏‏‎‏‏‏‏‏‎‏‎‏‏‏‎‎‎‏‏‎‎‎‏‎‎‎‎‏‏‎‎‏‏‏‎‎‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ has not accessed your camera‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‏‎‎‎‏‏‏‎‏‎‏‎‏‎‏‎‏‏‏‏‎‎‎‏‎‎‏‎‏‎‎‏‎‎‎‏‏‎‏‏‎‎‎‏‏‏‎‏‏‏‏‎‏‏‏‎‎‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ has not accessed your contacts‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‏‎‎‏‎‎‎‏‎‏‏‎‎‏‏‏‎‎‏‏‎‎‏‎‏‏‎‎‎‎‏‏‎‎‎‎‏‎‏‎‏‏‏‎‏‏‎‏‏‏‎‏‏‎‏‎‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ has not accessed your location‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‏‏‎‏‏‎‏‏‏‏‎‎‎‏‎‎‏‎‏‏‏‏‏‎‎‏‏‎‏‎‏‎‏‎‏‏‎‎‎‎‎‎‎‎‏‏‎‎‏‏‏‏‎‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ has not accessed your microphone‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‏‎‎‎‎‎‎‏‎‏‎‎‏‎‏‏‏‏‏‏‎‎‎‎‎‎‎‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‏‎‏‎‎‎‏‎‏‏‎‏‏‎‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ has not accessed your phone‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‎‎‏‎‏‏‏‏‏‎‎‏‏‏‎‎‏‏‏‎‏‎‎‎‏‏‎‏‎‎‏‏‎‏‏‏‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‏‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ has not accessed your sensors‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‎‏‏‏‎‎‏‎‏‏‎‏‏‏‎‏‏‏‎‎‎‏‎‏‎‎‏‏‏‏‏‎‎‏‎‎‎‎‏‏‎‎‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ has not accessed your SMS‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‎‎‎‏‎‎‏‏‎‎‏‏‎‎‎‏‎‏‎‏‎‏‎‎‎‏‎‎‎‎‎‏‎‏‎‎‏‎‏‏‏‎‎‏‏‏‏‎‏‎‏‎‎‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ has not accessed your storage‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‏‏‎‎‎‎‏‏‏‏‎‏‎‎‎‎‎‎‏‏‏‏‏‎‏‎‏‎‎‏‏‏‎‏‎‎‏‎‎‎‏‏‎‎‏‎‎‎‏‏‏‎‎Last access data is currently not available for this permission‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‏‏‎‏‏‏‏‏‏‎‎‎‎‎‏‎‏‏‎‏‏‎‎‎‎‎‎‏‎‏‎‎‎‏‏‎‎‏‏‏‏‎‎‎‎‏‏‏‏‎‏‏‎‎See all ‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ permissions‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‏‏‏‎‏‎‏‏‏‎‎‎‏‎‎‎‎‏‏‎‎‏‏‏‎‏‏‎‎‎‏‎‎‎‏‎‏‎‎‏‎‎‎‏‎‏‎‏‎‏‏‎‎See all apps with this permission‎‏‎‎‏‎" diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml index 0325640ce..395acd0c1 100644 --- a/res/values-es-rUS/strings.xml +++ b/res/values-es-rUS/strings.xml @@ -38,7 +38,7 @@ "ninguno inhabilitado" "Permitir" "Permitir todo el tiempo" - "Permitir solo con app en uso" + "Permitir solo con la app en uso" "Permitir todo el tiempo" "Apps" "Permisos de la app" @@ -73,7 +73,7 @@ "Permitir todo el tiempo" - "Permitir solo con app en uso" + "Permitir solo con la app en uso" "Denegar" "Cargando…" "Todos los permisos" @@ -94,7 +94,7 @@ "Desconocida" "Panel" "Último acceso: Se accedió por última vez a las %1$s\n cuando la app estaba en uso" - "Último acceso: Se accedió por última vez a las %1$s\nen segundo plano" + "Último acceso: %1$s\nÚltimo acceso en segundo plano" "Cualquier permiso" "Cualquier momento" "Últimos 7 días" @@ -141,12 +141,34 @@ "Acceso: %1$s veces Último uso: hace %2$s" "Permitir" "Permitir todo el tiempo" - "Permitir solo con app en uso" + "Permitir solo con la app en uso" "Rechazar" "Permiso de %1$s" "Acceso a %1$s para esta app" - "%1$s accedió a tu %2$s hace %3$s" - "%1$s no accedió a tu %2$s" + "%1$s accedió a tu %2$s hace %3$s" + "%1$s accedió a la actividad física hace %2$s" + "%1$s accedió al calendario hace %2$s" + "%1$s accedió al registro de llamadas hace %2$s" + "%1$s accedió a la cámara hace %2$s" + "%1$s accedió a los contactos hace %2$s" + "%1$s accedió a la ubicación hace %2$s" + "%1$s accedió al micrófono hace %2$s" + "%1$s accedió al teléfono hace %2$s" + "%1$s accedió a los sensores hace %2$s" + "%1$s accedió a los SMS hace %2$s" + "%1$s accedió al almacenamiento hace %2$s" + "%1$s no accedió a tu %2$s" + "%1$s no accedió a la actividad física" + "%1$s no accedió al calendario" + "%1$s no accedió al registro de llamadas" + "%1$s no accedió a la cámara" + "%1$s no accedió a los contactos" + "%1$s no accedió a la ubicación" + "%1$s no accedió al micrófono" + "%1$s no accedió al teléfono" + "%1$s no accedió a los sensores" + "%1$s no accedió a los SMS" + "%1$s no accedió al almacenamiento" "Por el momento, los datos del último acceso no están disponibles con este permiso" "Ver todos los permisos de %1$s" "Ver todas las apps que tienen este permiso" diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index caced22e6..bcc7b9301 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -145,8 +145,30 @@ "Denegar" "Permiso de %1$s" "Acceso a %1$s para esta aplicación" - "%1$s ha accedido a tu %2$s hace %3$s" - "%1$s no ha accedido a tu %2$s" + "%1$s accedió a tu %2$s hace %3$s" + "%1$s accedió a tu actividad física hace %2$s" + "%1$s accedió a tu calendario hace %2$s" + "%1$s accedió a tus registros de llamadas hace %2$s" + "%1$s accedió a tu cámara hace %2$s" + "%1$s accedió a tus contactos hace %2$s" + "%1$s accedió a tu ubicación hace %2$s" + "%1$s accedió a tu micrófono hace %2$s" + "%1$s accedió a tu teléfono hace %2$s" + "%1$s accedió a tus sensores hace %2$s" + "%1$s accedió a tus SMS hace %2$s" + "%1$s accedió a tu almacenamiento hace %2$s" + "%1$s no ha accedido a tu %2$s" + "%1$s no ha accedido a tu actividad física" + "%1$s no ha accedido a tu calendario" + "%1$s no ha accedido a tus registros de llamadas" + "%1$s no ha accedido a tu cámara" + "%1$s no ha accedido a tus contactos" + "%1$s no ha accedido a tu ubicación" + "%1$s no ha accedido a tu micrófono" + "%1$s no ha accedido a tu teléfono" + "%1$s no ha accedido a tus sensores" + "%1$s no ha accedido a tus SMS" + "%1$s no ha accedido a tu almacenamiento" "Los datos del último acceso de este permiso no está disponibles ahora mismo" "Ver todos los permisos de %1$s" "Ver todas las aplicaciones con este permiso" diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml index 7053df402..cb7bb883b 100644 --- a/res/values-et/strings.xml +++ b/res/values-et/strings.xml @@ -145,8 +145,30 @@ "Keela" "Luba %1$s" "Üksuse %1$s juurdepääs sellele rakendusele" - "Rakendus %1$s pääses üksusele %2$s juurde %3$s tagasi" - "%1$s pole loale %2$s juurde pääsenud" + "Rakendus %1$s pääses teie loale %2$s juurde %3$s tagasi" + "Rakendus %1$s pääses teie füüsilist. tegevustele juurde %2$s tagasi" + "Rakendus %1$s pääses teie kalendrile juurde %2$s tagasi" + "Rakendus %1$s pääses teie kõnelogidele juurde %2$s tagasi" + "Rakendus %1$s pääses teie kaamerale juurde %2$s tagasi" + "Rakendus %1$s pääses teie kontaktidele juurde %2$s tagasi" + "Rakendus %1$s pääses teie asukohale juurde %2$s tagasi" + "Rakendus %1$s pääses teie mikrofonile juurde %2$s tagasi" + "Rakendus %1$s pääses teie telefonile juurde %2$s tagasi" + "Rakendus %1$s pääses teie anduritele juurde %2$s tagasi" + "Rakendus %1$s pääses teie SMS-idele juurde %2$s tagasi" + "Rakendus %1$s pääses teie salvestusruumile juurde %2$s tagasi" + "Rakendus %1$s pole teie loale %2$s juurde pääsenud" + "Rakendus %1$s pole teie füüsilistele tegevustele juurde pääsenud" + "Rakendus %1$s pole teie kalendrile juurde pääsenud" + "Rakendus %1$s pole teie kõnelogidele juurde pääsenud" + "Rakendus %1$s pole teie kaamerale juurde pääsenud" + "Rakendus %1$s pole teie kontaktidele juurde pääsenud" + "Rakendus %1$s pole teie asukohale juurde pääsenud" + "Rakendus %1$s pole teie mikrofonile juurde pääsenud" + "Rakendus %1$s pole teie telefonile juurde pääsenud" + "Rakendus %1$s pole teie anduritele juurde pääsenud" + "Rakendus %1$s pole teie SMS-idele juurde pääsenud" + "Rakendus %1$s pole teie salvestusruumile juurde pääsenud" "Andmed viimase juurdepääsu kohta ei ole selle loa puhul praegu saadaval" "Kuva rakenduse %1$s kõik load" "Kuva kõik selle loaga rakendused" diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml index af7c32e91..9754acd0f 100644 --- a/res/values-eu/strings.xml +++ b/res/values-eu/strings.xml @@ -145,8 +145,30 @@ "Ukatu" "%1$s atzitzeko baimena" "Aplikazioak %1$s atzitzeko duen baimena" - "%1$s aplikazioak duela %3$s atzitu du %2$s" - "%1$s aplikazioak ez du atzitu %2$s" + "%1$s aplikazioak %2$s atzitu du duela %3$s" + "%1$s aplikazioak ariketa fisikoaren informazioa atzitu du duela %2$s" + "%1$s aplikazioak egutegia atzitu du duela %2$s" + "%1$s aplikazioak deien erregistroak atzitu ditu duela %2$s" + "%1$s aplikazioak kamera atzitu du duela %2$s" + "%1$s aplikazioak kontaktuak atzitu ditu duela %2$s" + "%1$s aplikazioak kokapena atzitu du duela %2$s" + "%1$s aplikazioak mikrofonoa atzitu du duela %2$s" + "%1$s aplikazioak telefonoa atzitu du duela %2$s" + "%1$s aplikazioak sentsoreak atzitu ditu duela %2$s" + "%1$s aplikazioak SMSak atzitu ditu duela %2$s" + "%1$s aplikazioak biltegia atzitu du duela %2$s" + "%1$s aplikazioak ez du atzitu %2$s" + "%1$s aplikazioak ez du atzitu ariketa fisikoaren informazioa" + "%1$s aplikazioak ez du atzitu egutegia" + "%1$s aplikazioak ez ditu atzitu deien erregistroak" + "%1$s aplikazioak ez du atzitu kamera" + "%1$s aplikazioak ez ditu atzitu kontaktuak" + "%1$s aplikazioak ez du atzitu kokapena" + "%1$s aplikazioak ez du atzitu mikrofonoa" + "%1$s aplikazioak ez du atzitu telefonoa" + "%1$s aplikazioak ez ditu atzitu sentsoreak" + "%1$s aplikazioak ez ditu atzitu SMSak" + "%1$s aplikazioak ez du atzitu biltegia" "Ez dituzte erabilgarri azken sarbidearen datuak baimen hau duten aplikazioek" "Ikusi %1$s aplikazioaren baimen guztiak" "Ikusi baimen hau duten aplikazio guztiak" diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml index 6061e7b88..a26cc48f2 100644 --- a/res/values-fa/strings.xml +++ b/res/values-fa/strings.xml @@ -101,7 +101,7 @@ "۲۴ ساعت اخیر" "۱ ساعت اخیر" "۱۵ دقیقه اخیر" - "۱ دقیقه آخر" + "۱ دقیقه اخیر" "هیچ مجوزی استفاده نشده است" "آخرین دسترسی در هرزمانی" "آخرین دسترسی در ۷ روز گذشته" @@ -145,8 +145,30 @@ "اجازه ندادن" "مجوز %1$s" "دسترسی %1$s برای این برنامه" - "%1$s %3$s پیش به %2$s دسترسی یافت" - "%1$s به %2$s دسترسی پیدا نکرده است" + "%1$s %3$s پیش به %2$s دسترسی یافت" + "%1$s %2$s پیش به فعالیت فیزیکی شما دسترسی پیدا کرد" + "%1$s %2$s پیش به تقویم شما دسترسی پیدا کرد" + "%1$s %2$s پیش به گزارش‌های تماس شما دسترسی پیدا کرد" + "%1$s %2$s پیش به دوربین شما دسترس پیدا کرد" + "%1$s %2$s پیش به مخاطبین شما دسترسی پیدا کرد" + "%1$s %2$s پیش به مکان شما دسترسی پیدا کرد" + "%1$s %2$s پیش به میکروفون شما دسترسی پیدا کرد" + "%1$s %2$s پیش به تلفن شما دسترسی پیدا کرد" + "%1$s %2$s پیش به حسگرهای شما دسترسی پیدا کرد" + "%1$s %2$s پیش به پیامک شما دسترسی پیدا کرد" + "%1$s %2$s پیش به فضای ذخیره‌سازی شما دسترسی پیدا کرد" + "%1$s به %2$s دسترسی پیدا نکرده است" + "%1$s به فعالیت فیزیکی شما دسترسی پیدا نکرده است" + "%1$s به تقویم شما دسترسی پیدا نکرده است" + "%1$s به گزارش‌های تماس شما دسترسی پیدا نکرده است" + "%1$s به دوربین شما دسترسی پیدا نکرده است" + "%1$s به مخاطبین شما دسترسی پیدا نکرده است" + "%1$s به مکان شما دسترسی پیدا نکرده است" + "%1$s به میکروفون شما دسترسی پیدا نکرده است" + "%1$s به تلفن شما دسترسی پیدا نکرده است" + "%1$s به حسگرهای شما دسترسی پیدا نکرده است" + "%1$s به پیامک شما دسترسی پیدا نکرده است" + "%1$s به فضای ذخیره‌سازی شما دسترسی پیدا نکرده است" "داده‌هایی که اخیراً به آن‌ها دسترسی پیدا کرده‌اید درحال‌حاضر برای این مجوز دردسترس نیست" "مشاهده همه مجوزهای %1$s" "دیدن همه برنامه‌هایی که این مجوز را دارند" diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml index 3f947b672..b74a8b465 100644 --- a/res/values-fi/strings.xml +++ b/res/values-fi/strings.xml @@ -145,8 +145,30 @@ "Estä" "Käyttöoikeus: %1$s" "Sovellus pyytää käyttöoikeutta: %1$s" - "%2$s oli sovelluksen (%1$s) käytössä %3$s sitten" - "%1$s ei ole käyttänyt tätä: %2$s" + "%1$s käytti tietojasi (%2$s) %3$s sitten" + "%1$s käytti liikkumistietojasi %2$s sitten" + "%1$s käytti kalenteriasi %2$s sitten" + "%1$s käytti puhelulokejasi %2$s sitten" + "%1$s käytti kameraasi %2$s sitten" + "%1$s käytti yhteystietojasi %2$s sitten" + "%1$s käytti sijaintiasi %2$s sitten" + "%1$s käytti mikrofoniasi %2$s sitten" + "%1$s käytti puhelintasi %2$s sitten" + "%1$s käytti antureitasi %2$s sitten" + "%1$s käytti tekstiviestejäsi %2$s sitten" + "%1$s käytti tallennustilaasi %2$s sitten" + "%1$s ei ole käyttänyt tätä: %2$s" + "%1$s ei ole käyttänyt liikkumistietojasi" + "%1$s ei ole käyttänyt kalenteriasi" + "%1$s ei ole käyttänyt puhelulokejasi" + "%1$s ei ole käyttänyt kameraasi" + "%1$s ei ole käyttänyt yhteystietojasi" + "%1$s ei ole käyttänyt sijaintiasi" + "%1$s ei ole käyttänyt mikrofoniasi" + "%1$s ei ole käyttänyt puhelintasi" + "%1$s ei ole käyttänyt antureitasi" + "%1$s ei ole käyttänyt tekstiviestejäsi" + "%1$s ei ole käyttänyt tallennustilaasi" "Tämän käyttöoikeuden viimeisen käyttökerran tietoja ei ole tällä hetkellä saatavilla" "Näytä kaikki käyttöoikeudet: %1$s" "Näytä kaikki sovellukset, joilla on tämä käyttöoikeus" diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml index dee6d34d4..9950a8ebb 100644 --- a/res/values-fr-rCA/strings.xml +++ b/res/values-fr-rCA/strings.xml @@ -143,10 +143,32 @@ "Autoriser tout le temps" "Autoriser uniquement lorsque l\'appli est en cours d\'utilisation" "Refuser" - "Autorisation %1$s" + "Autorisation : %1$s" "Accès demandé pour cette application : %1$s" - "%1$s a accédé à votre (vos) %2$s il y a %3$s" - "L\'application %1$s n\'a pas accédé à votre (vos) %2$s" + "%1$s a accédé à votre %2$s il y a %3$s" + "%1$s a accédé à votre activité physique il y a %2$s" + "%1$s a accédé à votre agenda il y a %2$s" + "%1$s a accédé à vos journaux d\'appel il y a %2$s" + "%1$s a accédé à votre appareil photo il y a %2$s" + "%1$s a accédé à vos contacts il y a %2$s" + "%1$s a accédé à votre position il y a %2$s" + "%1$s a accédé à votre microphone il y a %2$s" + "%1$s a accédé à votre téléphone il y a %2$s" + "%1$s a accédé à vos capteurs il y a %2$s" + "%1$s a accédé à vos messages texte il y a %2$s" + "%1$s a accédé à votre espace de stockage il y a %2$s" + "%1$s n\'a pas accédé à votre %2$s" + "%1$s n\'a pas accédé à votre activité physique" + "%1$s n\'a pas accédé à votre agenda" + "%1$s n\'a pas accédé à vos journaux d\'appel" + "%1$s n\'a pas accédé à votre appareil photo" + "%1$s n\'a pas accédé à vos contacts" + "%1$s n\'a pas accédé à votre position" + "%1$s n\'a pas accédé à votre microphone" + "%1$s n\'a pas accédé à votre téléphone" + "%1$s n\'a pas accédé à vos capteurs" + "%1$s n\'a pas accédé à vos messages texte" + "%1$s n\'a pas accédé à votre espace de stockage" "Les données relative au dernier accès ne sont pas présentement accessibles pour cette autorisation" "Afficher toutes les autorisations pour %1$s" "Afficher toutes les applications qui possèdent cette autorisation" @@ -225,9 +247,9 @@ "Applications qui vous permettent d\'enregistrer vos données médicales et de les rendre accessibles aux intervenants d\'urgence; pour recevoir des alertes sur des événements météorologiques graves et des désastres naturels; pour avertir d\'autres personnes lorsque vous avez besoin d\'aide" "Définir %1$s comme application par défaut pour les urgences?" "Aucune autorisation nécessaire" - "Application d\'accueil par défaut" + "Appli d\'accueil par défaut" "Application d\'accueil" - "Les applications qui remplacent les écrans d\'accueil sur votre appareil Android et qui vous donnent accès au contenu et aux fonctionnalités de votre appareil, qu\'on appelle souvent « lanceur d\'applications »" + "Applications qui remplacent les écrans d\'accueil sur votre appareil Android et qui vous donnent accès au contenu et aux fonctionnalités de votre appareil" "Définir %1$s comme application d\'accueil par défaut?" "Aucune autorisation nécessaire" "Appli redirect. appel par déf." diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index 55446381e..55fcd621c 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -38,7 +38,7 @@ "aucune désactivée" "Autoriser" "Toujours autoriser" - "Autoriser seulement si l\'application est ouverte" + "Autoriser seulement si l\'appli est en cours d\'utilisation" "Toujours autoriser" "Applications" "Autorisations des applications" @@ -73,7 +73,7 @@ "Toujours autoriser" - "Autoriser si appli ouverte" + "Autoriser si appli utilisée" "Refuser" "Chargement…" "Toutes les autorisations" @@ -141,12 +141,34 @@ "Accès : %1$s fois. Dernière utilisation il y a %2$s." "Autoriser" "Toujours autoriser" - "Autoriser seulement si l\'application est ouverte" + "Autoriser seulement si l\'appli est en cours d\'utilisation" "Refuser" "Autorisation : %1$s" "%1$s : accès pour cette application" - "L\'appli %1$s a accédé à votre/vos %2$s il y a %3$s" - "L\'appli %1$s n\'a pas accédé à votre/vos %2$s" + "%1$s a accédé à votre/vos %2$s il y a %3$s" + "%1$s a accédé à votre activité physique il y a %2$s" + "%1$s a accédé à votre agenda il y a %2$s" + "%1$s a accédé à vos journaux d\'appels il y a %2$s" + "%1$s a accédé à votre appareil photo il y a %2$s" + "%1$s a accédé à vos contacts il y a %2$s" + "%1$s a accédé à votre position il y a %2$s" + "%1$s a accédé à votre micro il y a %2$s" + "%1$s a accédé à votre téléphone il y a %2$s" + "%1$s a accédé à vos capteurs il y a %2$s" + "%1$s a accédé à vos SMS il y a %2$s" + "%1$s a accédé à votre espace de stockage il y a %2$s" + "%1$s n\'a pas accédé à votre/vos %2$s" + "%1$s n\'a pas accédé à votre activité physique" + "%1$s n\'a pas accédé à votre agenda" + "%1$s n\'a pas accédé à vos journaux d\'appels" + "%1$s n\'a pas accédé à votre appareil photo" + "%1$s n\'a pas accédé à vos contacts" + "%1$s n\'a pas accédé à votre position" + "%1$s n\'a pas accédé à votre micro" + "%1$s n\'a pas accédé à votre téléphone" + "%1$s n\'a pas accédé à vos capteurs" + "%1$s n\'a pas accédé à vos SMS" + "%1$s n\'a pas accédé à votre espace de stockage" "Les données relatives au dernier accès ne sont actuellement pas disponibles pour cette autorisation" "Afficher toutes les autorisations pour %1$s" "Afficher toutes les applications disposant de cette autorisation" diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml index 791dc8a63..ac0ff1f69 100644 --- a/res/values-gl/strings.xml +++ b/res/values-gl/strings.xml @@ -145,8 +145,30 @@ "Denegar" "Permiso de %1$s" "Permiso de acceso desta aplicación a: %1$s" - "A aplicación %1$s accedeu hai %3$s a: %2$s" - "A aplicación %1$s non ten acceso a: %2$s" + "A aplicación %1$s accedeu hai %3$s a: %2$s" + "A aplicación %1$s accedeu á túa actividade física hai %2$s" + "A aplicación %1$s accedeu ao teu calendario hai %2$s" + "A aplicación %1$s accedeu ao teu rexistro de chamadas hai %2$s" + "A aplicación %1$s accedeu á túa cámara hai %2$s" + "A aplicación %1$s accedeu aos teus contactos hai %2$s" + "A aplicación %1$s accedeu á túa localización hai %2$s" + "A aplicación %1$s accedeu ao teu micrófono hai %2$s" + "A aplicación %1$s accedeu ao teu teléfono hai %2$s" + "A aplicación %1$s accedeu aos teus sensores hai %2$s" + "A aplicación %1$s accedeu á túa SMS hai %2$s" + "A aplicación %1$s accedeu ao teu almacenamento hai %2$s" + "A aplicación %1$s non accedeu a: %2$s" + "A aplicación %1$s non accedeu á túa actividade física" + "A aplicación %1$s non accedeu ao teu calendario" + "A aplicación %1$s non accedeu aos teus rexistros de chamadas" + "A aplicación %1$s non accedeu á túa cámara" + "A aplicación %1$s non accedeu aos teus contactos" + "A aplicación %1$s non accedeu á túa localización" + "A aplicación %1$s non accedeu ao teu micrófono" + "A aplicación %1$s non accedeu ao teu teléfono" + "A aplicación %1$s non accedeu aos teus sensores" + "A aplicación %1$s non accedeu á túa SMS" + "A aplicación %1$s non accedeu ao teu almacenamento" "Os datos relativos ao último acceso non están dispoñibles para este permiso" "Ver todos os permisos de %1$s" "Ver todas as aplicacións que teñen este permiso" @@ -210,7 +232,7 @@ "Aplicacións que che permiten acceder a Internet e abrir as ligazóns que tocas" "Queres definir %1$s como a túa aplicación predeterminada de navegación?" "Non se necesita ningún permiso" - "App do teléfono predeterminada" + "App de teléfono predeterminada" "Aplicación de teléfono" "Aplicacións que che permiten realizar e recibir chamadas telefónicas utilizando o teu dispositivo" "Queres definir %1$s como a túa aplicación predeterminada de teléfono?" @@ -235,10 +257,10 @@ "Aplicacións que che permiten desviar chamadas a outro número de teléfono" "Queres definir %1$s como a túa aplicación predeterminada de desvío de chamadas?" "Non se necesita ningún permiso" - "App predet. de identif. de chamadas e spam" + "App de filtro de chamadas e spam predefinida" "App ident. de chamadas e spam" "Aplicacións que che permiten identificar as chamadas entrantes, bloquear o spam e as chamadas automatizadas, engadir os números non desexados á lista negra e realizar outras accións similares" - "Queres definir %1$s como a túa aplicación predeterminada de identificador de chamadas e spam?" + "Queres definir %1$s como a túa aplicación predeterminada de identificación de chamadas e spam?" "Non se necesita ningún permiso" "App predeterminada actual" "Non preguntar de novo" @@ -259,8 +281,8 @@ "(Opción predeterminada do sistema)" "Non hai ningunha aplicación" "acceso especial das aplicacións" - "Acceso especial as aplicacións" - "Sen acceso especial ás apps" + "Acceso especial das aplicacións" + "Sen acceso especial das apps" "Non hai ningunha aplicación" "Non é compatible co perfil de traballo" "Nota: Se reinicias o dispositivo e definiches un bloqueo de pantalla, esta aplicación non se poderá iniciar ata que desbloquees o dispositivo." diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml index a7c4311ec..6c48607a0 100644 --- a/res/values-gu/strings.xml +++ b/res/values-gu/strings.xml @@ -145,11 +145,33 @@ "નકારો" "%1$s પરવાનગી" "આ ઍપ માટે %1$sનો ઍક્સેસ" - "%1$sએ તમારી %2$sને %3$s પહેલાં ઍક્સેસ કરી" - "%1$sએ તમારા %2$sનો ઍક્સેસ મેળવ્યો નથી" + "%1$sએ તમારી %2$sને %3$s પહેલાં ઍક્સેસ કરી હતી" + "%1$s%2$s પહેલાં તમારી શારીરિક પ્રવૃત્તિને ઍક્સેસ કરી હતી" + "%1$s%2$s પહેલાં તમારું કૅલેન્ડર ઍક્સેસ કર્યું હતું" + "%1$s%2$s પહેલાં તમારો કૉલ લૉગ ઍક્સેસ કર્યો હતો" + "%1$s%2$s પહેલાં તમારો કૅમેરો ઍક્સેસ કર્યો હતો" + "%1$s%2$s પહેલાં તમારા સંપર્કોને ઍક્સેસ કર્યા હતા" + "%1$s%2$s પહેલાં તમારી સ્થાન સેવા ઍક્સેસ કરી હતી" + "%1$s%2$s પહેલાં તમારો માઇક્રોફોન ઍક્સેસ કર્યો હતો" + "%1$s%2$s પહેલાં તમારા ફોનને ઍક્સેસ કર્યો હતો" + "%1$s%2$s પહેલાં તમારા સેન્સર ઍક્સેસ કર્યા હતા" + "%1$s%2$s પહેલાં તમારી SMS સેવા ઍક્સેસ કરી હતી" + "%1$s%2$s પહેલાં તમારો સ્ટોરેજ ઍક્સેસ કર્યો હતો" + "%1$sએ તમારી %2$sને ઍક્સેસ કરી નથી" + "%1$sએ તમારી શારીરિક પ્રવૃત્તિ ઍક્સેસ કરી નથી" + "%1$sએ તમારું કૅલેન્ડર ઍક્સેસ કર્યું નથી" + "%1$sએ તમારો કૉલ લૉગ ઍક્સેસ કર્યો નથી" + "%1$sએ તમારો કૅમેરો ઍક્સેસ કર્યો નથી" + "%1$sએ તમારા સંપર્કો ઍક્સેસ કર્યા નથી" + "%1$sએ તમારી સ્થાન સેવા ઍક્સેસ કરી નથી" + "%1$sએ તમારા માઇક્રોફોનને ઍક્સેસ કર્યું નથી" + "%1$sએ તમારા ફોનને ઍક્સેસ કર્યો નથી" + "%1$sએ તમારા સેન્સર ઍક્સેસ કર્યા નથી" + "%1$sએ તમારી SMS સેવા ઍક્સેસ કરી નથી" + "%1$sએ તમારી સ્ટોરેજ ઍક્સેસ કરી નથી" "આ પરવાનગી માટે છેલ્લે ઍક્સેસ કરેલો ડેટા હાલમાં ઉપલબ્ધ નથી" "%1$sની બધી પરવાનગીઓ જુઓ" - "આ પરવાનગી વડે બધી ઍપ જુઓ" + "આ પરવાનગી સાથે બધી ઍપ જુઓ" "આ પરવાનગી ધરાવતી ઍપ %1$s" "આ પરવાનગી ધરાવતી ઍપ તમારી શારીરિક પ્રવૃત્તિ જેમ કે ચાલવું, બાઇકિંગ, ડ્રાઇવિંગ, પગલાંની સંખ્યા અને બીજી ઘણી બધી પ્રવૃત્તિ ઍક્સેસ કરી શકે છે" "આ પરવાનગી ધરાવતી ઍપ તમારા કૅલેન્ડરને ઍક્સેસ કરી શકશે" diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml index 45f82fc80..1737fe667 100644 --- a/res/values-hi/strings.xml +++ b/res/values-hi/strings.xml @@ -145,8 +145,30 @@ "नामंज़ूर करें" "%1$s अनुमति" "इस ऐप्लिकेशन के लिए %1$s इस्तेमाल करने की अनुमति" - "%1$s ने %3$s पहले आपके %2$s को एक्सेस किया" - "%1$s ने आपका %2$s एक्सेस नहीं किया है" + "%1$s ने %3$s पहले आपकी %2$s एक्सेस की" + "%1$s ने %2$s पहले आपकी शारीरिक गतिविधि की जानकारी एक्सेस की" + "%1$s ने %2$s पहले आपका कैलेंडर एक्सेस किया" + "%1$s ने %2$s पहले आपके कॉल लॉग एक्सेस किए" + "%1$s ने %2$s पहले आपका कैमरा एक्सेस किया" + "%1$s ने %2$s पहले आपके संपर्क एक्सेस किए" + "%1$s ने %2$s पहले आपकी जगह की जानकारी एक्सेस की" + "%1$s ने %2$s पहले आपका माइक्रोफ़ोन एक्सेस किया" + "%1$s ने %2$s पहले आपका फ़ोन एक्सेस किया" + "%1$s ने %2$s पहले आपके सेंसर एक्सेस किए" + "%1$s ने %2$s पहले आपके मैसेज (एसएमएस) एक्सेस किए" + "%1$s ने %2$s पहले आपके डिवाइस की मेमोरी एक्सेस की" + "%1$s ने आपकी %2$s एक्सेस नहीं की" + "%1$s ने आपकी शारीरिक गतिविधि की जानकारी एक्सेस नहीं की" + "%1$s ने आपका कैलेंडर एक्सेस नहीं किया" + "%1$s ने आपके कॉल लॉग एक्सेस नहीं किए" + "%1$s ने आपका कैमरा एक्सेस नहीं किया" + "%1$s ने आपके संपर्क एक्सेस नहीं किए" + "%1$s ने आपकी जगह की जानकारी एक्सेस नहीं की" + "%1$s ने आपका माइक्रोफ़ोन एक्सेस नहीं किया" + "%1$s ने आपका फ़ोन एक्सेस नहीं किया" + "%1$s ने आपके सेंसर एक्सेस नहीं किए" + "%1$s ने आपके मैसेज (एसएमएस) नहीं एक्सेस किए" + "%1$s ने आपके डिवाइस की मेमोरी एक्सेस नहीं की" "इस अनुमति के पिछली बार इस्तेमाल किए जाने का डेटा फ़िलहाल मौजूद नहीं है" "सभी %1$s अनुमतियां देखें" "इस अनुमति वाले सभी ऐप्लिकेशन देखें" diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml index 665fc40dc..7f35a97cc 100644 --- a/res/values-hr/strings.xml +++ b/res/values-hr/strings.xml @@ -148,8 +148,30 @@ "Odbij" "Dopuštenje %1$s" "Aplikacija ima pristup značajci: %1$s" - "Aplikacija %1$s pristupila je značajci \"%2$s\" prije %3$s" - "Aplikacija %1$s nije pristupila vašem dopuštenju %2$s" + "Aplikacija %1$s pristupila je dopuštenju %2$s prije %3$s" + "Aplikacija %1$s pristupila je tjelesnoj aktivnosti prije %2$s" + "Aplikacija %1$s pristupila je kalendaru prije %2$s" + "Aplikacija %1$s pristupila je zapisniku poziva prije %2$s" + "Aplikacija %1$s pristupila je fotoaparatu prije %2$s" + "Aplikacija %1$s pristupila je kontaktima prije %2$s" + "Aplikacija %1$s pristupila je lokaciji prije %2$s" + "Aplikacija %1$s pristupila je mikrofonu prije %2$s" + "Aplikacija %1$s pristupila je telefonu prije %2$s" + "Aplikacija %1$s pristupila je senzorima prije %2$s" + "Aplikacija %1$s pristupila je SMS-u prije %2$s" + "Aplikacija %1$s pristupila je pohrani prije %2$s" + "Aplikacija %1$s nije pristupila vašem dopuštenju %2$s" + "Aplikacija %1$s nije pristupila tjelesnoj aktivnosti" + "Aplikacija %1$s nije pristupila kalendaru" + "Aplikacija %1$s nije pristupila zapisniku poziva" + "Aplikacija %1$s nije pristupila fotoaparatu" + "Aplikacija %1$s nije pristupila kontaktima" + "Aplikacija %1$s nije pristupila lokaciji" + "Aplikacija %1$s nije pristupila mikrofonu" + "Aplikacija %1$s nije pristupila telefonu" + "Aplikacija %1$s nije pristupila senzorima" + "Aplikacija %1$s nije pristupila SMS-u" + "Aplikacija %1$s nije pristupila pohrani" "Podaci o posljednjem pristupu trenutačno nisu dostupni za ovo dopuštenje" "Pogledajte sva dopuštenja aplikacije %1$s" "Pogledajte sve aplikacije s tim dopuštenjem" diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml index 528da36d9..4ed284e65 100644 --- a/res/values-hu/strings.xml +++ b/res/values-hu/strings.xml @@ -145,8 +145,30 @@ "Tiltás" "%1$s – engedély" "Alkalmazás hozzáférése a következőhöz: %1$s" - "A(z) %1$s alkalmazás hozzáfért a következőhöz: %2$s (ennyi ideje: %3$s)" - "A(z) %1$s nem fért hozzá a következő engedélyhez: %2$s" + "A(z) %1$s alkalmazás hozzáfért a következőhöz: %2$s (ennyi ideje: %3$s)" + "A(z) %1$s hozzáfért a testmozgási adatokhoz (ennyi ideje: %2$s)" + "A(z) %1$s hozzáfért a naptárhoz (ennyi ideje: %2$s)" + "A(z) %1$s hozzáfért a hívásnaplóhoz (ennyi ideje: %2$s)" + "A(z) %1$s hozzáfért a kamerához (ennyi ideje: %2$s)" + "A(z) %1$s hozzáfért a névjegyekhez (ennyi ideje: %2$s)" + "A(z) %1$s hozzáfért a helyadatokhoz (ennyi ideje: %2$s)" + "A(z) %1$s hozzáfért a mikrofonhoz (ennyi ideje: %2$s)" + "A(z) %1$s hozzáfért a telefonhoz (ennyi ideje: %2$s)" + "A(z) %1$s hozzáfért az érzékelőkhöz (ennyi ideje: %2$s)" + "A(z) %1$s hozzáfért az SMS-ekhez (ennyi ideje: %2$s)" + "A(z) %1$s hozzáfért a tárhelyhez (ennyi ideje: %2$s)" + "A(z) %1$s nem fért hozzá a következő engedélyhez: %2$s" + "A(z) %1$s még nem fért hozzá a testmozgási adatokhoz" + "A(z) %1$s még nem fért hozzá a naptárhoz" + "A(z) %1$s még nem fért hozzá a hívásnaplóhoz" + "A(z) %1$s még nem fért hozzá a kamerához" + "A(z) %1$s még nem fért hozzá a névjegyekhez" + "A(z) %1$s még nem fért hozzá a helyadatokhoz" + "A(z) %1$s még nem fért hozzá a mikrofonhoz" + "A(z) %1$s még nem fért hozzá a telefonhoz" + "A(z) %1$s még nem fért hozzá az érzékelőkhöz" + "A(z) %1$s még nem fért hozzá az SMS-ekhez" + "A(z) %1$s még nem fért hozzá a tárhelyhez" "A legutóbbi hozzáférés adatai jelenleg nem állnak rendelkezésre ennél az engedélynél" "A(z) %1$s összes engedélyének megtekintése" "Az ezzel az engedéllyel rendelkező összes alkalmazás megtekintése" diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml index e82bee24a..6e304a554 100644 --- a/res/values-hy/strings.xml +++ b/res/values-hy/strings.xml @@ -145,8 +145,30 @@ "Մերժել" %1$s» թույլտվություն" "%1$sն օգտագործելու թույլտվություն այս հավելվածի համար" - "%1$s հավելվածը ստացել է «%2$s» թույլտվությունը %3$s առաջ" - "%1$s հավելվածին հասանելի չէ ձեր %2$sը:" + "%1$s հավելվածն օգտագործել է «%2$s» թույլտվությունը %3$s առաջ" + "%1$s հավելվածն օգտագործել է ձեր ֆիզիկական ակտիվությունը %2$s առաջ" + "%1$s հավելվածն օգտագործել է ձեր օրացույցը %2$s առաջ" + "%1$s հավելվածն օգտագործել է ձեր զանգերի մատյանը %2$s առաջ" + "%1$s հավելվածն օգտագործել է ձեր տեսախցիկը %2$s առաջ" + "%1$s հավելվածն օգտագործել է ձեր կոնտակտները %2$s առաջ" + "%1$s հավելվածն օգտագործել է ձեր տեղադրության տվյալները %2$s առաջ" + "%1$s հավելվածն օգտագործել է ձեր խոսափողը %2$s առաջ" + "%1$s հավելվածն օգտագործել է ձեր հեռախոսը %2$s առաջ" + "%1$s հավելվածն օգտագործել է ձեր տվիչները %2$s առաջ" + "%1$s հավելվածն օգտագործել է ձեր SMS-ները %2$s առաջ" + "%1$s հավելվածն օգտագործել է ձեր սարքի հիշողությունը %2$s առաջ" + "%1$s հավելվածը չի օգտագործել «%2$s» թույլտվությունը" + "%1$s հավելվածը չի օգտագործել ձեր ֆիզիկական ակտիվության տվյալները" + "%1$s հավելվածը չի օգտագործել ձեր օրացույցը" + "%1$s հավելվածը չի օգտագործել ձեր զանգերի մատյանը" + "%1$s հավելվածը չի օգտագործել ձեր տեսախցիկը" + "%1$s հավելվածը չի օգտագործել ձեր կոնտակտները" + "%1$s հավելվածը չի օգտագործել ձեր տեղադրության տվյալները" + "%1$s հավելվածը չի օգտագործել ձեր խոսափողը" + "%1$s հավելվածը չի օգտագործել ձեր հեռախոսը" + "%1$s հավելվածը չի օգտագործել ձեր տվիչները" + "%1$s հավելվածը չի օգտագործել ձեր SMS-ները" + "%1$s հավելվածը չի օգտագործել սարքի հիշողությունը" "Այս թույլտվության համար հասանելիության մասին տվյալներ չկան" "Դիտել %1$s հավելվածի բոլոր թույլտվությունները" "Դիտել այս թույլտվությունն ունեցող հավելվածների ցանկը" diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml index 6579538ea..0de7b1b87 100644 --- a/res/values-in/strings.xml +++ b/res/values-in/strings.xml @@ -145,8 +145,30 @@ "Tolak" "Izin %1$s" "Akses %1$s untuk aplikasi ini" - "%1$s mengakses %2$s Anda %3$s yang lalu" - "%1$s belum mengakses %2$s Anda" + "%1$s mengakses %2$s %3$s yang lalu" + "%1$s mengakses aktivitas fisik %2$s yang lalu" + "%1$s mengakses kalender %2$s yang lalu" + "%1$s mengakses log panggilan %2$s yang lalu" + "%1$s mengakses kamera %2$s yang lalu" + "%1$s mengakses kontak %2$s yang lalu" + "%1$s mengakses lokasi %2$s yang lalu" + "%1$s mengakses mikrofon %2$s yang lalu" + "%1$s mengakses ponsel %2$s yang lalu" + "%1$s mengakses sensor %2$s yang lalu" + "%1$s mengakses SMS %2$s yang lalu" + "%1$s mengakses penyimpanan %2$s yang lalu" + "%1$s belum mengakses %2$s" + "%1$s belum mengakses aktivitas fisik" + "%1$s belum mengakses kalender" + "%1$s belum mengakses log panggilan" + "%1$s belum mengakses kamera" + "%1$s belum mengakses kontak" + "%1$s belum mengakses lokasi" + "%1$s belum mengakses mikrofon" + "%1$s belum mengakses ponsel" + "%1$s belum mengakses sensor" + "%1$s belum mengakses SMS" + "%1$s belum mengakses penyimpanan" "Data akses terakhir saat ini tidak tersedia untuk izin ini" "Lihat semua izin %1$s" "Lihat semua aplikasi dengan izin ini" diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml index 3cd891673..3bd361c0f 100644 --- a/res/values-is/strings.xml +++ b/res/values-is/strings.xml @@ -145,8 +145,30 @@ "Hafna" "%1$s - heimild" "%1$s: Aðgangur fyrir þetta forrit" - "%2$s: %1$s fékk aðgang að fyrir %3$s" - "%1$s hefur ekki fengið aðgang að %2$s" + "%2$s: %1$s fékk aðgang fyrir %3$s" + "%1$s fékk aðgang að líkamsræktargögnunum þínum fyrir %2$s" + "%1$s fékk aðgang að dagatalinu þínu fyrir %2$s" + "%1$s fékk aðgang að símtalaskránum þínum fyrir %2$s" + "%1$s fékk aðgang að myndavélinni þinni fyrir %2$s" + "%1$s fékk aðgang að tengiliðunum þínum fyrir %2$s" + "%1$s fékk aðgang að staðsetningu þinni fyrir %2$s" + "%1$s fékk aðgang að hljóðnemanum þínum fyrir %2$s" + "%1$s fékk aðgang að símanum þínum fyrir %2$s" + "%1$s fékk aðgang að skynjurunum þínum fyrir %2$s" + "%1$s fékk aðgang að SMS hjá þér fyrir %2$s" + "%1$s fékk aðgang að geymslunni þinni fyrir %2$s" + "%1$s hefur ekki fengið aðgang að %2$s" + "%1$s hefur ekki fengið aðgang að líkamsræktargögnunum þínum" + "%1$s hefur ekki fengið aðgang að dagatalinu þínu" + "%1$s hefur ekki fengið aðgang að símtalaskránum þínum" + "%1$s hefur ekki fengið aðgang að myndavélinni þinni" + "%1$s hefur ekki fengið aðgang að tengiliðunum þínum" + "%1$s hefur ekki fengið aðgang að staðsetningu þinni" + "%1$s hefur ekki fengið aðgang að hljóðnemanum þínum" + "%1$s hefur ekki fengið aðgang að símanum þínum" + "%1$s hefur ekki fengið aðgang að skynjurunum þínum" + "%1$s hefur ekki fengið aðgang að SMS hjá þér" + "%1$s hefur ekki fengið aðgang að geymslunni þinni" "Sem stendur eru gögn um síðasta aðgang ekki tiltæk fyrir þessa heimild." "Sjá allar heimildir fyrir %1$s" "Sjá öll forrit með þessa heimild" diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml index 528548afa..72beccf95 100644 --- a/res/values-it/strings.xml +++ b/res/values-it/strings.xml @@ -145,8 +145,30 @@ "Rifiuta" "Autorizzazione %1$s" "Accesso a %1$s per questa app" - "%1$s ha avuto accesso a %2$s %3$s fa" - "%1$s non ha accesso a %2$s" + "%1$s ha avuto accesso a %2$s %3$s fa" + "%1$s ha avuto accesso alla tua attività fisica %2$s fa" + "%1$s ha avuto accesso al tuo calendario %2$s fa" + "%1$s ha avuto accesso al tuo registro chiamate %2$s fa" + "%1$s ha avuto accesso alla tua fotocamera %2$s fa" + "%1$s ha avuto accesso ai tuoi contatti %2$s fa" + "%1$s ha avuto accesso alla tua posizione %2$s fa" + "%1$s ha avuto accesso al tuo microfono %2$s fa" + "%1$s ha avuto accesso al tuo telefono %2$s fa" + "%1$s ha avuto accesso ai tuoi sensori %2$s fa" + "%1$s ha avuto accesso ai tuoi SMS %2$s fa" + "%1$s ha avuto accesso al tuo spazio di archiviazione %2$s fa" + "%1$s non ha avuto accesso a %2$s" + "%1$s non ha avuto accesso alla tua attività fisica" + "%1$s non ha avuto accesso al tuo calendario" + "%1$s non ha avuto accesso al tuo registro chiamate" + "%1$s non ha avuto accesso alla tua fotocamera" + "%1$s non ha avuto accesso ai tuoi contatti" + "%1$s non ha avuto accesso alla tua posizione" + "%1$s non ha avuto accesso al tuo microfono" + "%1$s non ha avuto accesso al tuo telefono" + "%1$s non ha avuto accesso ai tuoi sensori" + "%1$s non ha avuto accesso ai tuoi SMS" + "%1$s non ha avuto accesso al tuo spazio di archiviazione" "I dati sull\'ultimo accesso non sono al momento disponibili per questa autorizzazione" "Mostra tutte le autorizzazioni di %1$s" "Mostra tutte le app con questa autorizzazione" diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml index f38ad6147..99cd265c0 100644 --- a/res/values-iw/strings.xml +++ b/res/values-iw/strings.xml @@ -151,10 +151,32 @@ "אני לא מרשה" "הרשאה לאפליקציית %1$s" "אפליקציה זו יכולה לגשת אל %1$s" - "האפליקציה %1$s ניגשה אל %2$s לפני %3$s" - "האפליקציה %1$s לא ניגשה אל %2$s" + "האפליקציה %1$s ניגשה אל %2$s לפני %3$s" + "האפליקציה %1$s קיבלה גישה לפעילות הגופנית שלך לפני %2$s" + "האפליקציה %1$s קיבלה גישה ליומן שלך לפני %2$s" + "האפליקציה %1$s קיבלה גישה ליומני השיחות שלך לפני %2$s" + "האפליקציה %1$s קיבלה גישה למצלמה שלך לפני %2$s" + "האפליקציה %1$s קיבלה גישה לאנשי הקשר שלך לפני %2$s" + "האפליקציה %1$s קיבלה גישה למיקום שלך לפני %2$s" + "האפליקציה %1$s קיבלה גישה למיקרופון שלך לפני %2$s" + "האפליקציה %1$s קיבלה גישה לטלפון שלך לפני %2$s" + "האפליקציה %1$s קיבלה גישה לחיישנים שלך לפני %2$s" + "‏האפליקציה %1$s קיבלה גישה ל-SMS לפני %2$s" + "האפליקציה %1$s קיבלה גישה לאחסון שלך לפני %2$s" + "האפליקציה %1$s לא ניגשה אל %2$s" + "האפליקציה %1$s לא ניגשה לפעילות הגופנית שלך" + "האפליקציה %1$s לא ניגשה אל היומן שלך" + "האפליקציה %1$s לא ניגשה ליומני השיחות שלך" + "האפליקציה %1$s לא ניגשה אל המצלמה שלך" + "האפליקציה %1$s לא ניגשה אל אנשי הקשר שלך" + "האפליקציה %1$s לא ניגשה אל המיקום שלך" + "האפליקציה %1$s לא ניגשה למיקרופון שלך" + "האפליקציה %1$s לא ניגשה לטלפון שלך" + "האפליקציה %1$s לא ניגשה אל החיישנים שלך" + "‏האפליקציה %1$s לא ניגשה אל ה-SMS" + "האפליקציה %1$s לא ניגשה אל האחסון שלך" "נתוני הגישה האחרונה לא זמינים עכשיו להרשאה זו" - "הצגת כל ההרשאות של %1$s" + "הצגת כל ההרשאות של \'%1$s\'" "הצגת כל האפליקציות עם ההרשאה הזו" "אפליקציות עם ההרשאה הזו יכולות %1$s" "אפליקציות עם ההרשאה הזו יכולות לקבל גישה לפעילות הגופנית שלך, למשל הליכה, רכיבה על אופניים, נהיגה, ספירת צעדים ועוד" diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml index 554050ec5..456ace00d 100644 --- a/res/values-ja/strings.xml +++ b/res/values-ja/strings.xml @@ -145,8 +145,30 @@ "許可しない" "%1$sの権限" "このアプリの%1$sへのアクセス権限" - "%1$s%3$s前に%2$sにアクセスしました" - "%1$sはユーザーの%2$sにアクセスしていません" + "%1$s%3$s前に%2$sにアクセスしました" + "%1$s%2$s前に運動データにアクセスしました" + "%1$s%2$s前にカレンダーにアクセスしました" + "%1$s%2$s前に通話履歴にアクセスしました" + "%1$s%2$s前にカメラにアクセスしました" + "%1$s%2$s前に連絡先にアクセスしました" + "%1$s%2$s前に位置情報にアクセスしました" + "%1$s%2$s前にマイクにアクセスしました" + "%1$s%2$s前にスマートフォンにアクセスしました" + "%1$s%2$s前にセンサーにアクセスしました" + "%1$s%2$s前に SMS にアクセスしました" + "%1$s%2$s前にストレージにアクセスしました" + "%1$s%2$sにアクセスしていません" + "%1$sは運動データにアクセスしていません" + "%1$sはカレンダーにアクセスしていません" + "%1$sが通話履歴にアクセスしました" + "%1$sはカメラにアクセスしていません" + "%1$sは連絡先にアクセスしていません" + "%1$sは位置情報にアクセスしていません" + "%1$sはマイクにアクセスしていません" + "%1$sはスマートフォンにアクセスしていません" + "%1$sはセンサーにアクセスしていません" + "%1$sは SMS にアクセスしていません" + "%1$sはストレージにアクセスしていません" "現在、この権限の最終アクセスデータはご利用いただけません" "%1$sの権限をすべて表示" "この権限があるアプリをすべて表示" diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml index a9f0adff6..bd6e74d11 100644 --- a/res/values-ka/strings.xml +++ b/res/values-ka/strings.xml @@ -145,8 +145,30 @@ "უარყოფა" "ნებართვა: %1$s" "%1$s წვდომა ამ აპისთვის" - "%1$s-მა გამოიყენა თქვენი %2$s %3$sს წინ" - "%1$s-ს არ გამოუყენებია თქვენი %2$s" + "%1$s-მა თქვენი %2$s გამოიყენა %3$sს წინ" + "%1$s-მა თქვენი ფიზიკური აქტივობა გამოიყენა %2$sს წინ" + "%1$s-მა თქვენი კალენდარი გამოიყენა %2$sს წინ" + "%1$s-მა თქვენი ზარების ჟურნალი გამოიყენა %2$sს წინ" + "%1$s-მა თქვენი კამერა გამოიყენა %2$sს წინ" + "%1$s-მა თქვენი კონტაქტები გამოიყენა %2$sს წინ" + "%1$s-მა თქვენი მდებარეობა გამოიყენა %2$sს წინ" + "%1$s-მა თქვენი მიკროფონი გამოიყენა %2$sს წინ" + "%1$s-მა თქვენი ტელეფონი გამოიყენა %2$sს წინ" + "%1$s-მა თქვენი სენსორები გამოიყენა %2$sს წინ" + "%1$s-მა თქვენი SMS-ები გამოიყენა %2$sს წინ" + "%1$s-მა თქვენი მეხსიერება გამოიყენა %2$sს წინ" + "%1$s-ს არ გამოუყენებია თქვენი %2$s" + "%1$s-ს არ გამოუყენებია თქვენი ფიზიკური აქტივობა" + "%1$s-ს არ გამოუყენებია თქვენი კალენდარი" + "%1$s-ს არ გამოუყენებია თქვენი ზარების ჟურნალი" + "%1$s-ს არ გამოუყენებია თქვენი კამერა" + "%1$s-ს არ გამოუყენებია თქვენი კონტაქტები" + "%1$s-ს არ გამოუყენებია თქვენი მდებარეობა" + "%1$s-ს არ გამოუყენებია თქვენი მიკროფონი" + "%1$s-ს არ გამოუყენებია თქვენი ტელეფონი" + "%1$s-ს არ გამოუყენებია თქვენი სენსორები" + "%1$s-ს არ გამოუყენებია თქვენი SMS-ები" + "%1$s-ს არ გამოუყენებია თქვენი მეხსიერება" "ბოლო წვდომის მონაცემები ამ ნებართვისთვის ამჟამად მიუწვდომელია" "ყველა %1$s ნებართვის ნახვა" "ამ ნებართვის მქონე ყველა აპის ნახვა" diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml index c3577137e..aa5e3bbef 100644 --- a/res/values-kk/strings.xml +++ b/res/values-kk/strings.xml @@ -145,8 +145,30 @@ "Тыйым салу" "%1$s рұқсаты" "%1$s: осы қолданбаны пайдалану рұқсаты" - "%1$s қолданбасы %2$s рұқсатын %3$s бұрын пайдаланды." - "%1$s қолданбасы %2$s рұқсатын пайдаланбаған." + "%1$s қолданбасы %2$s рұқсатын %3$s бұрын пайдаланды." + "%1$s қолданбасы физикалық әрекетті тануды %2$s бұрын пайдаланды." + "%1$s қолданбасы күнтізбені %2$s бұрын пайдаланды." + "%1$s қолданбасы қоңыраулар журналын %2$s бұрын пайдаланды." + "%1$s қолданбасы камераны %2$s бұрын пайдаланды." + "%1$s қолданбасы контактілерді %2$s бұрын пайдаланды." + "%1$s қолданбасы геодеректі %2$s бұрын пайдаланды." + "%1$s қолданбасы микрофонды %2$s бұрын пайдаланды." + "%1$s қолданбасы телефонды %2$s бұрын пайдаланды." + "%1$s қолданбасы датчиктерді %2$s бұрын пайдаланды." + "%1$s қолданбасы SMS қызметін %2$s бұрын пайдаланды." + "%1$s қолданбасы жадты %2$s бұрын пайдаланды." + "%1$s қолданбасы %2$s рұқсатын пайдаланбады." + "%1$s қолданбасы физикалық әрекетті тануды пайдаланбады." + "%1$s қолданбасы күнтізбені пайдаланбады." + "%1$s қолданбасы қоңыраулар журналын пайдаланбады." + "%1$s қолданбасы камераны пайдаланбады." + "%1$s қолданбасы контактілерді пайдаланбады." + "%1$s қолданбасы геодеректі пайдаланбады." + "%1$s қолданбасы микрофонды пайдаланбады." + "%1$s қолданбасы телефонды пайдаланбады." + "%1$s қолданбасы датчиктерді пайдаланбады." + "%1$s қолданбасы SMS қызметін пайдаланбады." + "%1$s қолданбасы жадты пайдаланбады." "Бұл рұқсат үшін соңғы пайдалану деректері қазір қолжетімді емес." "Барлық %1$s рұқсаттарын көру" "Осы рұқсатқа ие барлық қолданбаларды көру" diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml index 3fec5f5a5..5ac86d26a 100644 --- a/res/values-km/strings.xml +++ b/res/values-km/strings.xml @@ -145,8 +145,30 @@ "បដិសេធ" "ការអនុញ្ញាត %1$s" "ការចូលប្រើ %1$s សម្រាប់​កម្មវិធី​នេះ​" - "%1$s បាន​ចូលប្រើ %2$s របស់អ្នកកាលពី %3$s មុន" - "%1$s មិន​បាន​ចូលប្រើ %2$s របស់អ្នក​ទេ" + "%1$s បាន​ចូលប្រើ %2$s របស់អ្នកកាលពី %3$s មុន" + "%1$s បាន​ចូលប្រើ​សកម្មភាពរាងកាយ​របស់អ្នក​កាលពី %2$s មុន" + "%1$s បាន​ចូលប្រើ​ប្រតិទិន​របស់អ្នក​កាលពី %2$s មុន" + "%1$s បាន​ចូលប្រើ​កំណត់ហេតុហៅទូរសព្ទ​របស់អ្នក​កាលពី %2$s មុន" + "%1$s បានចូលប្រើ​កាមេរ៉ា​របស់អ្នក​កាលពី %2$s មុន" + "%1$s បាន​ចូលប្រើ​ទំនាក់ទំនង​របស់អ្នក​កាលពី %2$s មុន" + "%1$s បាន​ចូលប្រើ​ទីតាំង​របស់អ្នក​កាលពី %2$s មុន" + "%1$s បាន​ចូលប្រើ​មីក្រូហ្វូន​របស់អ្នក​កាលពី %2$s មុន" + "%1$s បាន​ចូលប្រើ​ទូរសព្ទ​របស់អ្នក​កាលពី %2$s មុន" + "%1$s បាន​ចូលប្រើ​ឧបករណ៍ចាប់សញ្ញា​របស់អ្នក​កាលពី %2$s មុន" + "%1$s បាន​ចូលប្រើ​សារ SMS របស់អ្នក​កាលពី %2$s មុន" + "%1$s បាន​ចូលប្រើ​ទំហំផ្ទុក​របស់អ្នក​កាលពី %2$s មុន" + "%1$s មិន​បាន​ចូលប្រើ %2$s របស់អ្នក​ទេ" + "%1$s មិនបាន​ចូលប្រើ​សកម្មភាព​រាងកាយ​របស់អ្នក​ទេ" + "%1$s មិនបាន​ចូលប្រើ​ប្រតិទិន​របស់អ្នក​ទេ" + "%1$s មិនបាន​ចូលប្រើ​កំណត់ហេតុហៅទូរសព្ទ​របស់អ្នក​ទេ" + "%1$s មិនបាន​ចូលប្រើ​កាមេរ៉ា​របស់អ្នក​ទេ" + "%1$s មិនបាន​ចូលប្រើ​ទំនាក់ទំនង​របស់អ្នក​ទេ" + "%1$s មិនបាន​ចូលប្រើ​ទីតាំង​របស់អ្នក​ទេ" + "%1$s មិនបាន​ចូលប្រើ​មីក្រូហ្វូន​របស់អ្នក​ទេ" + "%1$s មិនបាន​ចូលប្រើ​ទូរសព្ទ​របស់អ្នក​ទេ" + "%1$s មិនបាន​ចូលប្រើ​ឧបករណ៍ចាប់សញ្ញា​របស់អ្នក​ទេ" + "%1$s មិនបាន​ចូលប្រើ​សារ SMS របស់អ្នក​ទេ" + "%1$s មិនបាន​ចូលប្រើ​ទំហំផ្ទុក​របស់អ្នក​ទេ" "បច្ចុប្បន្ន ទិន្នន័យអំពីការចូលប្រើប្រាស់ចុងក្រោយមិនមានសម្រាប់ការ​អនុញ្ញាត​នេះទេ" "មើល​ការអនុញ្ញាតឱ្យទៅ %1$s ទាំងអស់" "មើលកម្មវិធី​ទាំងអស់​ដែលមាន​ការអនុញ្ញាត​នេះ" diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml index 44218b8b0..1a8385a2c 100644 --- a/res/values-kn/strings.xml +++ b/res/values-kn/strings.xml @@ -123,7 +123,7 @@ "ಈ ಆಧಾರದ ಮೇಲೆ ಫಿಲ್ಟರ್ ಮಾಡಲಾಗಿದೆ: %1$s" "ಎಲ್ಲವನ್ನು ಡ್ಯಾಶ್ ಬೋರ್ಡ್‌ನಲ್ಲಿ ನೋಡಿ" "ಈ ಪ್ರಕಾರ ಫಿಲ್ಟರ್" - "ಅನುಮತಿಗಳ ಮೂಲಕ ಫಿಲ್ಟರ್ ಮಾಡಿ" + "ಅನುಮತಿಗಳ ಪ್ರಕಾರ ಫಿಲ್ಟರ್ ಮಾಡಿ" "ಸಮಯದ ಪ್ರಕಾರ ಫಿಲ್ಟರ್ ಮಾಡಿ" "ಹೆಚ್ಚಿನ ಅನುಮತಿಗಳು" "ಹೆಚ್ಚಿನ ಪ್ರವೇಶಗಳು" @@ -145,8 +145,30 @@ "ನಿರಾಕರಿಸಿ" "%1$s ಅನುಮತಿ" "ಈ %1$s ಆ್ಯಪ್‌ಗಾಗಿ ಪ್ರವೇಶದ ಅನುಮತಿ" - "%1$s ಆ್ಯಪ್ ನಿಮ್ಮ %2$s ಸ್ಥಳವನ್ನು %3$s ಹಿಂದೆ ಪ್ರವೇಶಿಸಿದೆ" - "%1$s ಆ್ಯಪ್ ನಿಮ್ಮ %2$s ಸ್ಥಳವನ್ನು ಪ್ರವೇಶಿಸಿಲ್ಲ" + "%1$s ಆ್ಯಪ್ ನಿಮ್ಮ %2$s ಸ್ಥಳವನ್ನು %3$s ಸಮಯದ ಹಿಂದೆ ಪ್ರವೇಶಿಸಿದೆ" + "%1$s ಆ್ಯಪ್ ನಿಮ್ಮ ದೈಹಿಕ ಚಟುವಟಿಕೆಯನ್ನು %2$s ಸಮಯದ ಹಿಂದೆ ಪ್ರವೇಶಿಸಿದೆ" + "%1$s ಆ್ಯಪ್ ನಿಮ್ಮ ಕ್ಯಾಲೆಂಡರ್ ಅನ್ನು %2$s ಸಮಯದ ಹಿಂದೆ ಪ್ರವೇಶಿಸಿದೆ" + "%1$s ಆ್ಯಪ್ ನಿಮ್ಮ ಕರೆಯ ಲಾಗ್‌ಗಳನ್ನು %2$s ಸಮಯದ ಹಿಂದೆ ಪ್ರವೇಶಿಸಿದೆ" + "%1$s ಆ್ಯಪ್ ನಿಮ್ಮ ಕ್ಯಾಮರಾವನ್ನು %2$s ಸಮಯದ ಹಿಂದೆ ಪ್ರವೇಶಿಸಿದೆ" + "%1$s ಆ್ಯಪ್ ನಿಮ್ಮ ಸಂಪರ್ಕಗಳನ್ನು %2$s ಸಮಯದ ಹಿಂದೆ ಪ್ರವೇಶಿಸಿದೆ" + "%1$s ಆ್ಯಪ್ ನಿಮ್ಮ ಸ್ಥಳವನ್ನು %2$s ಸಮಯದ ಹಿಂದೆ ಪ್ರವೇಶಿಸಿದೆ" + "%1$s ಆ್ಯಪ್ ನಿಮ್ಮ ಮೈಕ್ರೋಫೋನ್ ಅನ್ನು %2$s ಸಮಯದ ಹಿಂದೆ ಪ್ರವೇಶಿಸಿದೆ" + "%1$s ಆ್ಯಪ್ ನಿಮ್ಮ ಫೋನ್ ಅನ್ನು %2$s ಸಮಯದ ಹಿಂದೆ ಪ್ರವೇಶಿಸಿದೆ" + "%1$s ಆ್ಯಪ್ ನಿಮ್ಮ ಸೆನ್ಸರ್‌ಗಳನ್ನು %2$s ಸಮಯದ ಹಿಂದೆ ಪ್ರವೇಶಿಸಿದೆ" + "%1$s ಆ್ಯಪ್ ನಿಮ್ಮ ಎಸ್‌ಎಂಎಸ್ ಅನ್ನು %2$s ಸಮಯದ ಹಿಂದೆ ಪ್ರವೇಶಿಸಿದೆ" + "%1$s ಆ್ಯಪ್ ನಿಮ್ಮ ಸಂಗ್ರಹಣೆಯನ್ನು %2$s ಸಮಯದ ಹಿಂದೆ ಪ್ರವೇಶಿಸಿದೆ" + "%1$s ಆ್ಯಪ್ ನಿಮ್ಮ %2$s ಸ್ಥಳವನ್ನು ಪ್ರವೇಶಿಸಿಲ್ಲ" + "%1$s ಆ್ಯಪ್ ನಿಮ್ಮ ದೈಹಿಕ ಚಟುವಟಿಕೆಯನ್ನು ಪ್ರವೇಶಿಸಿಲ್ಲ" + "%1$s ಆ್ಯಪ್ ನಿಮ್ಮ ಕ್ಯಾಲೆಂಡರ್ ಅನ್ನು ಪ್ರವೇಶಿಸಿಲ್ಲ" + "%1$s ಆ್ಯಪ್ ನಿಮ್ಮ ಕರೆಯ ಲಾಗ್‌ಗಳನ್ನು ಪ್ರವೇಶಿಸಿಲ್ಲ" + "%1$s ಆ್ಯಪ್ ನಿಮ್ಮ ಕ್ಯಾಮರಾವನ್ನು ಪ್ರವೇಶಿಸಿಲ್ಲ" + "%1$s ಆ್ಯಪ್ ನಿಮ್ಮ ಸಂಪರ್ಕಗಳನ್ನು ಪ್ರವೇಶಿಸಿಲ್ಲ" + "%1$s ಆ್ಯಪ್ ನಿಮ್ಮ ಸ್ಥಳವನ್ನು ಪ್ರವೇಶಿಸಿಲ್ಲ" + "%1$s ಆ್ಯಪ್ ನಿಮ್ಮ ಮೈಕ್ರೋಫೋನ್ ಅನ್ನು ಪ್ರವೇಶಿಸಿಲ್ಲ" + "%1$s ಆ್ಯಪ್ ನಿಮ್ಮ ಫೋನ್ ಅನ್ನು ಪ್ರವೇಶಿಸಿಲ್ಲ" + "%1$s ಆ್ಯಪ್ ನಿಮ್ಮ ಸೆನ್ಸರ್‌ಗಳನ್ನು ಪ್ರವೇಶಿಸಿಲ್ಲ" + "%1$s ಆ್ಯಪ್ ನಿಮ್ಮ ಎಸ್‌ಎಂಎಸ್ ಅನ್ನು ಪ್ರವೇಶಿಸಿಲ್ಲ" + "%1$s ಆ್ಯಪ್ ನಿಮ್ಮ ಸಂಗ್ರಹಣೆಯನ್ನು ಪ್ರವೇಶಿಸಿಲ್ಲ" "ಈ ಅನುಮತಿಗಾಗಿ ಈ ಹಿಂದೆ ಪ್ರವೇಶಿಸಿದ ಡೇಟಾ ಪ್ರಸ್ತುತ ಲಭ್ಯವಿಲ್ಲ" "ಎಲ್ಲಾ %1$s ಅನುಮತಿಗಳನ್ನು ವೀಕ್ಷಿಸಿ" "ಈ ಅನುಮತಿಯನ್ನು ಹೊಂದಿರುವ ಎಲ್ಲಾ ಆ್ಯಪ್‌ಗಳನ್ನು ವೀಕ್ಷಿಸಿ" diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml index 4e6a4bdf9..4c834f290 100644 --- a/res/values-ko/strings.xml +++ b/res/values-ko/strings.xml @@ -145,8 +145,30 @@ "거부" "%1$s 액세스 권한" "이 앱의 %1$s 액세스 권한" - "%3$s 전에 %1$s 앱이 %2$s에 액세스했습니다." - "%1$s 앱이 %2$s에 액세스하지 않았습니다." + "%3$s%1$s 앱이 %2$s에 액세스했습니다." + "%2$s%1$s 앱이 신체 활동에 액세스했습니다." + "%2$s%1$s 앱이 캘린더에 액세스했습니다." + "%2$s%1$s 앱이 통화 기록에 액세스했습니다." + "%2$s%1$s 앱이 카메라에 액세스했습니다." + "%2$s%1$s 앱이 연락처에 액세스했습니다." + "%2$s%1$s 앱이 위치에 액세스했습니다." + "%2$s%1$s 앱이 마이크에 액세스했습니다." + "%2$s%1$s 앱이 휴대전화에 액세스했습니다." + "%2$s%1$s 앱이 센서에 액세스했습니다." + "%2$s%1$s 앱이 SMS에 액세스했습니다." + "%2$s%1$s 앱이 저장용량에 액세스했습니다." + "%1$s 앱은 %2$s에 액세스하지 않았습니다." + "%1$s 앱은 신체 활동에 액세스하지 않았습니다." + "%1$s 앱은 캘린더에 액세스하지 않았습니다." + "%1$s 앱은 통화 기록에 액세스하지 않았습니다." + "%1$s 앱은 카메라에 액세스하지 않았습니다." + "%1$s 앱은 연락처에 액세스하지 않았습니다." + "%1$s 앱은 위치에 액세스하지 않았습니다." + "%1$s 앱은 마이크에 액세스하지 않았습니다." + "%1$s 앱은 휴대전화에 액세스하지 않았습니다." + "%1$s 앱은 센서에 액세스하지 않았습니다." + "%1$s 앱은 SMS에 액세스하지 않았습니다." + "%1$s 앱은 저장용량에 액세스하지 않았습니다." "현재 이 권한에 관한 마지막 액세스 데이터를 사용할 수 없습니다." "%1$s 앱 권한 모두 보기" "이 권한이 있는 앱 모두 보기" diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml index b5d3858c6..b1b187259 100644 --- a/res/values-ky/strings.xml +++ b/res/values-ky/strings.xml @@ -145,8 +145,30 @@ "Жок" "%1$s дайындарына уруксаттар" "%1$s: бул колдонмого уруксат берүү" - "%1$s %2$s уруксатын %3$s мурун колдонгон" - "%1$s колдонмосу төмөнкүгө уруксат алган жок: %2$s" + "%1$s %2$s уруксатын %3$s мурун колдонду" + "%1$s кыймыл-аракетиңизди %2$s мурун кирди" + "%1$s жылнаамаңызга %2$s мурун кирди" + "%1$s чалуулар таржымалыңызга %2$s мурун кирди" + "%1$s камераңызды %2$s мурун колдонду" + "%1$s байланыштарыңызды %2$s мурун колдонду" + "%1$s кайда жүргөнүңүздү %2$s мурун көрдү" + "%1$s микрофонуңузду %2$s мурун колдонду" + "%1$s телефонуңузга %2$s мурун кирди" + "%1$s сенсорлорду %2$s мурун колдонду" + "%1$s SMS билдирүүңүздү %2$s мурун окуду" + "%1$s сактагычыңызга %2$s мурун кирди" + "%1$s колдонмосу төмөнкүгө уруксат алган жок: %2$s" + "%1$s кыймыл-аракетиңизди колдонууга уруксат алган жок" + "%1$s жылнаамаңызды колдонууга уруксат алган жок" + "%1$s чалуулар таржымалыңызды колдонууга уруксат алган жок" + "%1$s камераңызды колдонууга уруксат алган жок" + "%1$s байланыштарыңызды колдонууга уруксат алган жок" + "%1$s кайда жүрөгүңүздү көрүүгө уруксат алган жок" + "%1$s микрофонуңузду колдонууга уруксат алган жок" + "%1$s телефонуңузду колдонууга уруксат алган жок" + "%1$s сенсорлорду колдонууга уруксат алган жок" + "%1$s SMS билдирүүлөрүңүздү көрүүгө уруксат алган жок" + "%1$s сактагычыңызды колдонууга уруксат алган жок" "Акыркы жолу колдонулган дайындарды бул уруксат менен көрүү мүмкүн эмес" "Бардык %1$s уруксаттарын көрүү" "Ушундай уруксат берилген бардык колдонмолорду көрүү" diff --git a/res/values-lo/strings.xml b/res/values-lo/strings.xml index 7de3366ab..f4e97336b 100644 --- a/res/values-lo/strings.xml +++ b/res/values-lo/strings.xml @@ -145,8 +145,30 @@ "ປະຕິເສດ" "ສິດອະນຸຍາດ %1$s" "%1$s ສິດເຂົ້າເຖິງສຳລັບແອັບນີ້" - "%1$s ເຂົ້າເຖິງ %2$s ຂອງທ່ານເມື່ອ %3$s ກ່ອນ" - "%1$s ບໍ່ໄດ້ເຂົ້າເຖິງ %2$s ຂອງທ່ານ" + "%1$s ເຂົ້າເຖິງ %2$s ຂອງທ່ານເມື່ອ %3$s ກ່ອນ" + "%1$s ເຂົ້າເຖິງສະຖານທີ່ທາງກາຍະພາບຂອງທ່ານ %2$s ກ່ອນ" + "%1$s ເຂົ້າເຖິງປະຕິທິນຂອງທ່ານ %2$s ກ່ອນ" + "%1$s ເຂົ້າເຖິງບັນທຶກການໂທຂອງທ່ານ %2$s ກ່ອນ" + "%1$s ເຂົ້າເຖິງກ້ອງຖ່າຍຮູບຂອງທ່ານ %2$s ກ່ອນ" + "%1$s ເຂົ້າເຖິງລາຍຊື່ຜູ້ຕິດຕໍ່ຂອງທ່ານ %2$s ກ່ອນ" + "%1$s ເຂົ້າເຖິງສະຖານທີ່ຂອງທ່ານ %2$s ກ່ອນ" + "%1$s ເຂົ້າເຖິງໄມໂຄຣໂຟນຂອງທ່ານ %2$s ກ່ອນ" + "%1$s ເຂົ້າເຖິງມືຖືຂອງທ່ານ %2$s ກ່ອນ" + "%1$s ເຂົ້າເຖິງເຊັນເຊີຂອງທ່ານ %2$s ກ່ອນ" + "%1$s ເຂົ້າເຖິງ SMS ຂອງທ່ານ %2$s ກ່ອນ" + "%1$s ເຂົ້າເຖິງບ່ອນຈັດເກັບຂໍ້ມູນຂອງທ່ານ %2$s ກ່ອນ" + "%1$s ບໍ່ໄດ້ເຂົ້າເຖິງ %2$s ຂອງທ່ານ" + "%1$s ບໍ່ໄດ້ເຂົ້າເຖິງສະຖານທີ່ທາງກາຍະພາບຂອງທ່ານ" + "%1$s ບໍ່ໄດ້ເຂົ້າເຖິງປະຕິທິນຂອງທ່ານ" + "%1$s ບໍ່ໄດ້ເຂົ້າເຖິງບັນທຶກການໂທຂອງທ່ານ" + "%1$s ບໍ່ໄດ້ເຂົ້າເຖິງກ້ອງຖ່າຍຮູບຂອງທ່ານ" + "%1$s ບໍ່ໄດ້ເຂົ້າເຖິງລາຍຊື່ຜູ້ຕິດຕໍ່ຂອງທ່ານ" + "%1$s ບໍ່ໄດ້ເຂົ້າເຖິງສະຖານທີ່ຂອງທ່ານ" + "%1$s ບໍ່ໄດ້ເຂົ້າເຖິງໄມໂຄຣໂຟນຂອງທ່ານ" + "%1$s ບໍ່ໄດ້ເຂົ້າເຖິງໂທລະສັບຂອງທ່ານ" + "%1$s ບໍ່ໄດ້ເຂົ້າເຖິງເຊັນເຊີຂອງທ່ານ" + "%1$s ບໍ່ໄດ້ເຂົ້າເຖິງ SMS ຂອງທ່ານ" + "%1$s ບໍ່ໄດ້ເຂົ້າເຖິງບ່ອນຈັດເກັບຂໍ້ມູນຂອງທ່ານ" "ຕອນນີ້ບໍ່ມີຂໍ້ມູນການເຂົ້າເຖິງຫຼ້າສຸດສຳລັບສິດອະນຸຍາດນີ້" "ເບິ່ງສິດອະນຸຍາດ %1$s ທັງໝົດ" "ເບິ່ງແອັບທັງໝົດທີ່ມີສິດອະນຸຍາດນີ້" diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml index b7520ca22..b04a5455a 100644 --- a/res/values-lt/strings.xml +++ b/res/values-lt/strings.xml @@ -151,8 +151,30 @@ "Atmesti" "Leidimas: %1$s" "%1$s: šios programos prieiga" - "Programa „%1$s“ prieš %3$s pasiekė: %2$s" - "Programa „%1$s“ nepasiekė: %2$s" + "Programa „%1$s“ prieš %3$s pasiekė: %2$s" + "Programa „%1$s“ prieš %2$s pasiekė jūsų fizinę veiklą" + "Programa „%1$s“ prieš %2$s pasiekė jūsų kalendorių" + "Programa „%1$s“ prieš %2$s pasiekė jūsų skambučių žurnalus" + "Programa „%1$s“ prieš %2$s pasiekė jūsų fotoaparatą" + "Programa „%1$s“ prieš %2$s pasiekė jūsų kontaktus" + "Programa „%1$s“ prieš %2$s pasiekė jūsų vietovę" + "Programa „%1$s“ prieš %2$s pasiekė jūsų mikrofoną" + "Programa „%1$s“ prieš %2$s pasiekė jūsų telefoną" + "Programa „%1$s“ prieš %2$s pasiekė jūsų jutiklius" + "Programa „%1$s“ prieš %2$s pasiekė jūsų SMS" + "Programa „%1$s“ prieš %2$s pasiekė jūsų saugyklą" + "Programa „%1$s“ nepasiekė: %2$s" + "Programa „%1$s“ nepasiekė jūsų fizinės veiklos" + "Programa „%1$s“ nepasiekė jūsų kalendoriaus" + "Programa „%1$s“ nepasiekė jūsų skambučių žurnalų" + "Programa „%1$s“ nepasiekė jūsų fotoaparato" + "Programa „%1$s“ nepasiekė jūsų kontaktų" + "Programa „%1$s“ nepasiekė jūsų vietovės" + "Programa „%1$s“ nepasiekė jūsų mikrofono" + "Programa „%1$s“ nepasiekė jūsų telefono" + "Programa „%1$s“ nepasiekė jūsų jutiklių" + "Programa „%1$s“ nepasiekė jūsų SMS" + "Programa „%1$s“ nepasiekė jūsų saugyklos" "Paskutinės prieigos duomenys šiuo metu turint šį leidimą nepasiekiami" "Žr. visus „%1$s“ leidimus" "Žr. visas programas, kurioms suteiktas šis leidimas" diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml index c7bc733bc..3d0b6f4cf 100644 --- a/res/values-lv/strings.xml +++ b/res/values-lv/strings.xml @@ -148,8 +148,30 @@ "Neatļaut" "Atļauja: %1$s" "%1$s: šīs lietotnes piekļuve" - "%1$s piekļuva jūsu atļaujai %2$s pirms: %3$s" - "Lietotnei %1$s nav piekļuves atļaujai %2$s" + "Lietotne %1$s piekļuva jūsu atļaujai %2$s pirms šāda laika: %3$s" + "Lietotne %1$s piekļuva jūsu fiziskajām aktivitātēm pirms: %2$s" + "Lietotne %1$s piekļuva jūsu kalendāram pirms šāda laika: %2$s" + "Lietotne %1$s piekļuva jūsu zvanu žurnālam pirms šāda laika: %2$s" + "Lietotne %1$s piekļuva jūsu kamerai pirms šāda laika: %2$s" + "Lietotne %1$s piekļuva jūsu kontaktpersonām pirms šāda laika: %2$s" + "Lietotne %1$s piekļuva jūsu atrašanās vietai pirms šāda laika: %2$s" + "Lietotne %1$s piekļuva jūsu mikrofonam pirms šāda laika: %2$s" + "Lietotne %1$s piekļuva jūsu tālrunim pirms šāda laika: %2$s" + "Lietotne %1$s piekļuva jūsu sensoriem pirms šāda laika: %2$s" + "Lietotne %1$s piekļuva jūsu īsziņām pirms šāda laika: %2$s" + "Lietotne %1$s piekļuva jūsu krātuvei pirms šāda laika: %2$s" + "Lietotnei %1$s nav piekļuves atļaujai %2$s" + "Lietotnei %1$s nav piekļuves jūsu fiziskajām aktivitātēm" + "Lietotnei %1$s nav piekļuves jūsu kalendāram" + "Lietotnei %1$s nav piekļuves jūsu zvanu žurnālam" + "Lietotnei %1$s nav piekļuves jūsu kamerai" + "Lietotnei %1$s nav piekļuves jūsu kontaktpersonām" + "Lietotnei %1$s nav piekļuves jūsu atrašanās vietai" + "Lietotnei %1$s nav piekļuves jūsu mikrofonam" + "Lietotnei %1$s nav piekļuves jūsu tālrunim" + "Lietotnei %1$s nav piekļuves jūsu sensoriem" + "Lietotnei %1$s nav piekļuves jūsu īsziņām" + "Lietotnei %1$s nav piekļuves jūsu krātuvei" "Dati par pēdējo piekļuvi pašlaik nav pieejami ar šo atļauju" "Skatīt visas lietotnei %1$s piešķirtās atļaujas" "Skatīt visas lietotnes, kam ir šī atļauja" diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml index 01c9d0d74..9f8034876 100644 --- a/res/values-mk/strings.xml +++ b/res/values-mk/strings.xml @@ -145,8 +145,30 @@ "Одбиј" "Пристап до %1$s" "Пристап до %1$s за апликацијава" - "%1$s пристапи до %2$s пред %3$s" - "%1$s не пристапила до %2$s" + "%1$s пристапи до %2$s пред %3$s" + "%1$s пристапи до вашата физичка активност пред %2$s" + "%1$s пристапи до вашиот календар пред %2$s" + "%1$s пристапи до вашата евиденција на повици пред %2$s" + "%1$s пристапи до вашата камера пред %2$s" + "%1$s пристапи до вашите контакти пред %2$s" + "%1$s пристапи до вашата локација пред %2$s" + "%1$s пристапи до вашиот микрофон пред %2$s" + "%1$s пристапи до вашиот телефон пред %2$s" + "%1$s пристапи до вашите сензори пред %2$s" + "%1$s пристапи до вашите SMS-пораки пред %2$s" + "%1$s пристапи до вашиот капацитет пред %2$s" + "%1$s не пристапи до %2$s" + "%1$s не пристапи до вашата физичка активност" + "%1$s не пристапи до вашиот календар" + "%1$s не пристапи до вашата евиденција на повици" + "%1$s не пристапи до вашата камера" + "%1$s не пристапи до вашите контакти" + "%1$s не пристапи до вашата локација" + "%1$s не пристапи до вашиот микрофон" + "%1$s не пристапи до вашиот телефон" + "%1$s не пристапи до вашите сензори" + "%1$s не пристапи до вашите SMS-пораки" + "%1$s не пристапи до вашиот капацитет" "Последните податоци за пристап не се достапни за оваа дозвола во моментов" "Прикажи ги сите дозволи за %1$s" "Прикажи ги сите апликации со оваа дозвола" diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml index 101b6ad18..cccea9711 100644 --- a/res/values-ml/strings.xml +++ b/res/values-ml/strings.xml @@ -145,8 +145,30 @@ "നിരസിക്കുക" "%1$s അനുമതി" "ഈ ആപ്പിനുള്ള %1$s ആക്‌സ‌സ്" - "നിങ്ങളുടെ %2$s %1$s എന്ന ആപ്പ് %3$s മുമ്പ് ആക്‌സസ് ചെയ്‌തു" - "%1$s നിങ്ങളുടെ %2$s ആക്‌സസ് ചെയ്‌തിട്ടില്ല" + "%3$s മുമ്പ് %1$s നിങ്ങളുടെ %2$s ആക്‌സസ് ചെയ്‌തു" + "%2$s മുമ്പ് %1$s നിങ്ങളുടെ ശാരീരിക പ്രവർത്തനം ആക്‌സസ് ചെയ്‌തു" + "%2$s മുമ്പ് %1$s നിങ്ങളുടെ കലണ്ടർ ആക്‌സസ് ചെയ്‌തു" + "%2$s മുമ്പ് %1$s നിങ്ങളുടെ കോൾ ചരിത്രങ്ങൾ ആക്‌സസ് ചെയ്‌തു" + "%2$s മുമ്പ് %1$s നിങ്ങളുടെ ക്യാമറ ആക്‌സസ് ചെയ്‌തു" + "%2$s മുമ്പ് %1$s നിങ്ങളുടെ കോൺടാക്‌റ്റുകൾ ആക്‌സസ് ചെയ്‌തു" + "%2$s മുമ്പ് %1$s നിങ്ങളുടെ ലൊക്കേഷൻ ആക്‌സസ് ചെയ്‌തു" + "%2$s മുമ്പ് %1$s നിങ്ങളുടെ മൈക്രോഫോൺ ആക്‌സസ് ചെയ്‌തു" + "%2$s മുമ്പ് %1$s നിങ്ങളുടെ ഫോൺ ആക്‌സസ് ചെയ്‌തു" + "%2$s മുമ്പ് %1$s നിങ്ങളുടെ സെൻസറുകൾ ആക്‌സസ് ചെയ്‌തു" + "%2$s മുമ്പ് %1$s നിങ്ങളുടെ SMS ആക്‌സസ് ചെയ്‌തു" + "%2$s മുമ്പ് %1$s നിങ്ങളുടെ സ്‌റ്റോറേജ് ആക്‌സസ് ചെയ്‌തു" + "%1$s നിങ്ങളുടെ %2$s ആക്‌സസ് ചെയ്‌തിട്ടില്ല" + "%1$s നിങ്ങളുടെ ശാരീരിക പ്രവർത്തനം ആക്‌‌സസ് ചെയ്‌തിട്ടില്ല" + "%1$s നിങ്ങളുടെ കലണ്ടർ ആക്‌സസ് ചെയ്‌തിട്ടില്ല" + "%1$s നിങ്ങളുടെ കോൾ ചരിത്രങ്ങൾ ആക്‌സസ് ചെയ്‌തു" + "%1$s നിങ്ങളുടെ ക്യാമറ ആക്‌സസ് ചെയ്‌തിട്ടില്ല" + "%1$s നിങ്ങളുടെ കോൺടാക്‌റ്റുകൾ ആക്‌സസ് ചെയ്‌തിട്ടില്ല" + "%1$s നിങ്ങളുടെ ലൊക്കേഷൻ ആക്‌സസ് ചെയ്‌തിട്ടില്ല" + "%1$s നിങ്ങളുടെ മൈക്രോഫോൺ ആക്‌സസ് ചെയ്‌തിട്ടില്ല" + "%1$s നിങ്ങളുടെ ഫോൺ ആക്‌സസ് ചെയ്‌തിട്ടില്ല" + "%1$s നിങ്ങളുടെ സെൻസറുകൾ ആക്‌സസ് ചെയ്‌തിട്ടില്ല" + "%1$s നിങ്ങളുടെ SMS ആക്‌സസ് ചെയ്‌തിട്ടില്ല" + "%1$s നിങ്ങളുടെ സ്‌റ്റോറേജ് ആക്‌സസ് ചെയ്‌തിട്ടില്ല" "ഈ അനുമതിക്കായുള്ള അവസാന ആക്‌സസ് ഡാറ്റ നിലവിൽ ലഭ്യമല്ല" "എല്ലാ %1$s അനുമതികളും കാണുക" "ഈ അനുമതിയുള്ള എല്ലാ ആപ്പുകളും കാണുക" @@ -217,7 +239,7 @@ "SMS അയയ്‌ക്കൽ, കോൾ ചരിത്രം എന്നിവയിലേക്ക് ആക്‌സസ് നേടുക" "ഡിഫോൾട്ട് SMS ആപ്പ്" "SMS ആപ്പ്" - "ചുരുക്കത്തിലുള്ള ടെക്‌സ്‌റ്റ് മെസേജുകൾ, ഫോട്ടോകൾ, വീഡിയോകൾ എന്നിവയും മറ്റും അയയ്ക്കാനും ലഭിക്കാനും നിങ്ങളുടെ ഫോൺ നമ്പർ ഉപയോഗിക്കാൻ അനുവദിക്കുന്ന ആപ്പുകൾ" + "ചുരുക്കത്തിലുള്ള ടെക്‌സ്‌റ്റ് മെസേജുകൾ, ഫോട്ടോകൾ, വീഡിയോകൾ എന്നിവയും മറ്റും അയയ്ക്കാനും സ്വീകരിക്കാനും നിങ്ങളുടെ ഫോൺ നമ്പർ ഉപയോഗിക്കാൻ അനുവദിക്കുന്ന ആപ്പുകൾ" "%1$s എന്നതിനെ നിങ്ങളുടെ ഡിഫോൾട്ട് SMS ആപ്പായി സജ്ജീകരിക്കണോ?" "കോൺടാക്‌റ്റുകൾ, SMS, ഫോൺ എന്നിവയിലേക്ക് ആക്‌സസ് നേടുക" "ഡിഫോൾട്ട് അടിയന്തിര ആപ്പ്" diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml index 7186035c0..04948aa18 100644 --- a/res/values-mn/strings.xml +++ b/res/values-mn/strings.xml @@ -145,8 +145,30 @@ "Татгалзах" "%1$s-н зөвшөөрөл" "Энэ аппад %1$s-р хандах" - "%1$s таны %2$s%3$s-н өмнө хандсан байна" - "%1$s таны %2$s-д хандаагүй байна" + "%1$s таны %2$s%3$s-н өмнө хандсан" + "%1$s таны дасгал хөдөлгөөний үйл ажиллагаанд %2$s-н өмнө хандсан" + "%1$s таны календарьт %2$s-н өмнө хандсан" + "%1$s таны дуудлагын жагсаалтад %2$s-н өмнө хандсан" + "%1$s таны камерт %2$s-н өмнө хандсан" + "%1$s таны харилцагчид %2$s-н өмнө хандсан" + "%1$s таны байршилд %2$s-н өмнө хандсан" + "%1$s таны микрофонд %2$s-н өмнө хандсан" + "%1$s таны утсанд %2$s-н өмнө хандсан" + "%1$s таны мэдрэгчид %2$s-н өмнө хандсан" + "%1$s таны мессежэд %2$s-н өмнө хандсан" + "%1$s таны хадгалах санд %2$s-н өмнө хандсан" + "%1$s таны %2$s-д хандаагүй" + "%1$s таны дасгал хөдөлгөөний үйл ажиллагаанд хандаагүй" + "%1$s таны календарьт хандаагүй" + "%1$s таны дуудлагын жагсаалтад хандаагүй" + "%1$s таны камерт хандаагүй" + "%1$s таны харилцагчид хандаагүй" + "%1$s таны байршилд хандаагүй" + "%1$s таны микрофонд хандаагүй" + "%1$s таны утсанд хандаагүй" + "%1$s таны мэдрэгчид хандаагүй" + "%1$s таны мессежэд хандаагүй" + "%1$s таны хадгалах санд хандаагүй" "Энэ зөвшөөрлийн хамгийн сүүлийн хандалтын өгөгдөл одоогоор боломжгүй байна" "%1$s-н бүх зөвшөөрлийг харах" "Энэ зөвшөөрөлтэй бүх аппыг харах" diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml index 41b9f058b..3413d140f 100644 --- a/res/values-mr/strings.xml +++ b/res/values-mr/strings.xml @@ -48,8 +48,8 @@ "अतिरिक्त परवानग्या" "अ‍ॅप माहिती उघडा" - अधिक %1$d अधिक %1$d + अधिक %1$d "हे अ‍ॅप Android च्या जुन्या आवृत्तीसाठी डीझाइन करण्यात आले होते. परवानगी नाकारल्यामुळे ते यापुढे अपेक्षित असल्याप्रमाणे कार्य करणार नाही." "अज्ञात क्रिया करा" @@ -116,8 +116,8 @@ "मागील १५ मिनिटांतील परवानगी वापर" "मागील एका मिनिटातील परवानगी वापर" - %s अ‍ॅप %s अ‍ॅप्स + एक अ‍ॅप "डॅशबोर्डमध्ये सर्व पहा" "यानुसार फिल्टर केले: %1$s" @@ -133,8 +133,8 @@ ", " "रिफ्रेश करा" - %s अ‍ॅप %s अ‍ॅप्स + एक अ‍ॅप "अ‍ॅप परवानग्यांचा वापर" "अॅक्सेस करा: %1$s वेळा. एकूण कालावधी: %2$s. %3$s पूर्वी शेवटचे वापरले." @@ -145,8 +145,30 @@ "नकार द्या" "%1$s परवानगी" "या अ‍ॅपसाठी %1$s अ‍ॅक्सेस केला" - "%1$s ने तुमचे %2$s %3$s पूर्वी अॅक्सेस केले" - "%1$s ने तुमचे %2$s अॅक्सेस केलेले नाही" + "%1$s ने %3$s पूर्वी तुमचे %2$s अ‍ॅक्सेस केले" + "%1$s ने %2$s पूर्वी तुमची शारीरिक अ‍ॅक्टिव्हिटी अ‍ॅक्सेस केली" + "%1$s ने %2$s पूर्वी तुमचे कॅलेंडर अ‍ॅक्सेस केले" + "%1$s ने %2$s पूर्वी तुमचे कॉल लॉग अ‍ॅक्सेस केले" + "%1$s ने %2$s पूर्वी तुमचा कॅमेरा अ‍ॅक्सेस केला" + "%1$s ने %2$s पूर्वी तुमचे संपर्क अ‍ॅक्सेस केले" + "%1$s ने %2$s पूर्वी तुमचे स्थान अ‍ॅक्सेस केले" + "%1$s ने %2$s पूर्वी तुमचा मायक्रोफोन अ‍ॅक्सेस केला" + "%1$s ने %2$s पूर्वी तुमचा फोन अ‍ॅक्सेस केला" + "%1$s ने %2$s पूर्वी तुमचे सेंसर अ‍ॅक्सेस केले" + "%1$s ने %2$s पूर्वी तुमचा एसएमएस अ‍ॅक्सेस केला" + "%1$s ने %2$s पूर्वी तुमचा स्टोरेज अ‍ॅक्सेस केला" + "%1$s ने तुमचे %2$s अ‍ॅक्सेस केलेले नाही" + "%1$s ने तुमची शारीरिक अ‍ॅक्टिव्हिटी अ‍ॅक्सेस केलेली नाही" + "%1$s ने तुमचे कॅलेंडर अ‍ॅक्सेस केलेले नाही" + "%1$s ने तुमचे कॉल लॉग अ‍ॅक्सेस केलेले नाहीत" + "%1$s ने तुमचा कॅमेराचा अ‍ॅक्सेस केलेला नाही" + "%1$s ने तुमचे संपर्क अ‍ॅक्सेस केलेले नाहीत" + "%1$s ने तुमचे स्थान अ‍ॅक्सेस केलेले नाही" + "%1$s ने तुमचा मायक्रोफोन अ‍ॅक्सेस केलेला नाही" + "%1$s ने तुमचा फोन अ‍ॅक्सेस केलेला नाही" + "%1$s ने तुमचे सेंसर अ‍ॅक्सेस केलेले नाहीत" + "%1$s ने तुमचा एसएमएस अ‍ॅक्सेस केलेला नाही" + "%1$s ने तुमचा स्टोरेज अ‍ॅक्सेस केलेला नाही" "या परवानगीसाठी शेवटचा अ‍ॅक्सेस केलेला डेटा सध्या उपलब्ध नाही" "सर्व %1$s परवानग्या पहा" "ही परवानगी असलेली सर्व अ‍ॅप्स पहा" @@ -159,7 +181,7 @@ "ही परवानगी असलेली अ‍ॅप्स या डिव्हाइसचे स्थान अ‍ॅक्सेस करू शकतात" "ही परवानगी असलेली अ‍ॅप्स ऑडिओ रेकॉर्ड करू शकतात" "ही परवानगी असलेली अ‍ॅप्स फोन कॉल करू आणि व्यवस्थापित करू शकतात" - "ही परवानगी असलेली अ‍ॅप्स तुमच्या महत्त्वाच्या लक्षणांबद्दलचा सेंसर डेटा अ‍ॅक्सेस करू शकतात" + "ही परवानगी असलेली अ‍ॅप्स तुमच्या महत्त्वाच्या लक्षणांबद्दलचा सेन्सर डेटा अ‍ॅक्सेस करू शकतात" "ही परवानगी असलेली अ‍ॅप्स एसएमएस मेसेज पाठवू आणि पाहू शकतात" "ही परवानगी असलेली अ‍ॅप्स तुमच्या डिव्हाइसवरील फोटो, मीडिया आणि फायली अ‍ॅक्सेस करू शकतात" "शेवटचा अ‍ॅक्सेस: %1$s" @@ -172,20 +194,20 @@ "नाकारलेली" "तपशीलवार वापर पाहा" - %s दिवस %s दिवस + एक दिवस - %s तास %s तास + एक तास - %s मिनिट %s मिनिटे + एक मिनिट - %s सेकंद %s सेकंद + एक सेकंद "परवानगी रिमाइंडर" "%s तुमचे स्थान वापरत आहे" diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml index 3d5ab3d3d..b5b8d822f 100644 --- a/res/values-ms/strings.xml +++ b/res/values-ms/strings.xml @@ -145,8 +145,30 @@ "Tolak" "Kebenaran %1$s" "Akses %1$s untuk apl ini" - "%1$s mengakses %2$s anda %3$s yang lalu" - "%1$s belum mengakses %2$s anda" + "%1$s mengakses %2$s anda %3$s yang lalu" + "%1$s mengakses aktiviti fizikal anda %2$s yang lalu" + "%1$s mengakses kalendar anda %2$s yang lalu" + "%1$s mengakses log panggilan anda %2$s yang lalu" + "%1$s mengakses kamera anda %2$s yang lalu" + "%1$s mengakses kenalan anda %2$s yang lalu" + "%1$s mengakses lokasi anda %2$s yang lalu" + "%1$s mengakses mikrofon anda %2$s yang lalu" + "%1$s mengakses telefon anda %2$s yang lalu" + "%1$s mengakses penderia anda %2$s yang lalu" + "%1$s mengakses SMS anda %2$s yang lalu" + "%1$s mengakses storan anda %2$s yang lalu" + "%1$s belum mengakses %2$s anda" + "%1$s belum mengakses aktiviti fizikal anda" + "%1$s belum mengakses kalendar anda" + "%1$s belum mengakses log panggilan anda" + "%1$s belum mengakses kamera anda" + "%1$s belum mengakses kenalan anda" + "%1$s belum mengakses lokasi anda" + "%1$s belum mengakses mikrofon anda" + "%1$s belum mengakses telefon anda" + "%1$s belum mengakses penderia anda" + "%1$s belum mengakses SMS anda" + "%1$s belum mengakses storan anda" "Data akses terakhir tidak tersedia untuk kebenaran ini pada masa ini" "Lihat semua kebenaran %1$s" "Lihat semua apl dengan kebenaran ini" diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml index c05268394..cdae09600 100644 --- a/res/values-my/strings.xml +++ b/res/values-my/strings.xml @@ -145,8 +145,30 @@ "ငြင်းပယ်ရန်" "%1$s ခွင့်ပြုချက်" "ဤအက်ပ်အတွက် %1$s အသုံးပြုခွင့်" - "%1$s က သင်၏ %2$s ကို ပြီးခဲ့သော %3$s က ဝင်သုံးထားသည်" - "%1$s က သင်၏ %2$s ကို ဝင်သုံးမထားပါ" + "%1$s က သင်၏ %2$s ကို ပြီးခဲ့သော %3$s က သုံးထားသည်" + "%1$s က သင့်ကိုယ်လက်လှုပ်ရှားမှုကို ပြီးခဲ့သော %2$s က ကြည့်ထားသည်" + "%1$s က သင့်ပြက္ခဒိန်ကို ပြီးခဲ့သော %2$s က သုံးထားသည်" + "%1$s က သင်ခေါ်ဆိုထားသော မှတ်တမ်းများကို ပြီးခဲ့သော %2$s က သုံးထားသည်" + "%1$s က သင့်ကင်မရာကို ပြီးခဲ့သော %2$s က သုံးထားသည်" + "%1$s သင့်အဆက်အသွယ်များကို ပြီးခဲ့သော %2$s က သုံးထားသည်" + "%1$s က သင့်တည်နေရာကို ပြီးခဲ့သော %2$s က သုံးထားသည်" + "%1$s က သင့်မိုက်ခရိုဖုန်းကို ပြီးခဲ့သော %2$s က သုံးထားသည်" + "%1$s က သင့်ဖုန်းကို ပြီးခဲ့သော %2$s က သုံးထားသည်" + "%1$s က သင့်အာရုံခံစနစ်များကို ပြီးခဲ့သော %2$s က သုံးထားသည်" + "%1$s က သင့် SMS စာတိုစနစ်ကို ပြီးခဲ့သော %2$s က သုံးထားသည်" + "%1$s က သင့်သိုလှောင်ခန်းကို ပြီးခဲ့သော %2$s က သုံးထားသည်" + "%1$s က သင်၏ %2$s ကို သုံးမထားပါ" + "%1$s က သင့်ကိုယ်လက်လှုပ်ရှားမှုကို ကြည့်မထားပါ" + "%1$s က သင့်ပြက္ခဒိန်ကို သုံးမထားပါ" + "%1$s က သင့်ခေါ်ဆိုထားသော မှတ်တမ်းများကို သုံးမထားပါ" + "%1$s က သင့်ကင်မရာကို သုံးမထားပါ" + "%1$s က သင့်အဆက်အသွယ်များကို သုံးမထားပါ" + "%1$s က သင့်တည်နေရာကို သုံးမထားပါ" + "%1$s က သင့်မိုက်ခရိုဖုန်းကို သုံးမထားပါ" + "%1$s က သင့်ဖုန်းကို သုံးမထားပါ" + "%1$s က သင့်အာရုံခံစနစ်များကို သုံးမထားပါ" + "%1$s က သင်၏ SMS စာတိုစနစ်ကို သုံးမထားပါ" + "%1$s က သင့်သိုလှောင်ခန်းကို သုံးမထားပါ" "ဤခွင့်ပြုချက်အတွက် နောက်ဆုံးဝင်သုံးထားသော ဒေတာကို လက်ရှိတွင် မရနိုင်ပါ" "%1$s ခွင့်ပြုချက်အားလုံး ကြည့်ရန်" "ဤခွင့်ပြုချက်ရှိသော အက်ပ်အားလုံးကို ကြည့်ရန်" diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml index 36167c5e2..06dce543c 100644 --- a/res/values-nb/strings.xml +++ b/res/values-nb/strings.xml @@ -145,9 +145,31 @@ "Avvis" "%1$stillatelse" "%1$stilgang for denne appen" - "%1$s brukte %2$s for %3$s siden" - "%1$s har ikke brukt %2$s" - "Data om forrige bruk er for øyeblikket utilgjengelig for denne tillatelsen" + "%1$s brukte %2$s for %3$s siden" + "%1$s brukte den fysiske aktiviteten din for %2$s siden" + "%1$s brukte kalenderen din for %2$s siden" + "%1$s brukte samtaleloggene dine for %2$s siden" + "%1$s brukte kameraet ditt for %2$s siden" + "%1$s brukte kontaktene dine for %2$s siden" + "%1$s brukte posisjonen din for %2$s siden" + "%1$s brukte mikrofonen din for %2$s siden" + "%1$s brukte telefonen din for %2$s siden" + "%1$s brukte sensorene dine for %2$s siden" + "%1$s brukte SMS for %2$s siden" + "%1$s brukte lagringsplassen din for %2$s siden" + "%1$s har ikke brukt %2$s" + "%1$s har ikke brukt den fysiske aktiviteten din" + "%1$s har ikke brukt kalenderen din" + "%1$s har ikke brukt samtaleloggene dine" + "%1$s har ikke brukt kameraet ditt" + "%1$s har ikke brukt kontaktene dine" + "%1$s har ikke brukt posisjonen din" + "%1$s har ikke brukt mikrofonen din" + "%1$s har ikke brukt telefonen din" + "%1$s har ikke brukt sensorene dine" + "%1$s har ikke brukt SMS" + "%1$s har ikke brukt lagringsplassen din" + "Data om forrige bruk er foreløpig ikke tilgjengelig for denne tillatelsen" "Se alle tillatelsene %1$s har" "Se alle apper med denne tillatelsen" "Apper med denne tillatelsen kan %1$s" @@ -194,7 +216,7 @@ "Ingen tillatelser er gitt" "Ingen tillatelser er nektet" "Ingen apper har denne tillatelsen" - "Ingen apper er nektet" + "Ingen apptillatelser er avvist" "Innstillinger" "%s har full tilgang til enheten din" "%s tilgjengelighetsapper har full tilgang til enheten din" diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml index f37f77e17..800653b9e 100644 --- a/res/values-ne/strings.xml +++ b/res/values-ne/strings.xml @@ -145,8 +145,30 @@ "अस्वीकार गर्नुहोस्‌" "%1$s अनुमति" "यस अनुप्रयोगमाथि %1$s पहुँच" - "%1$s ले %3$s अघि तपाईंको %2$s माथि पहुँच गर्‍यो" - "%1$s ले तपाईंको %2$s माथि पहुँच गरेको छैन" + "%1$s ले %3$s अघि तपाईंको %2$s माथि पहुँच राख्यो" + "%1$s ले %2$s अघि तपाईंको क्रियाकलापको डेटामाथि पहुँच राख्यो" + "%1$s ले %2$s अघि तपाईंको पात्रोमाथि पहुँच राख्यो" + "%1$s ले %2$s अघि तपाईंको कलका लगमाथि पहुँच राख्यो" + "%1$s ले %2$s अघि तपाईंको क्यामेरामाथि पहुँच राख्यो" + "%1$s ले %2$s अघि तपाईंका सम्पर्क ठेगानामाथि पहुँच राख्यो" + "%1$s ले %2$s अघि तपाईंको स्थानमाथि पहुँच राख्यो" + "%1$s ले %2$s अघि तपाईंको माइक्रोफोनमाथि पहुँच राख्यो" + "%1$s ले %2$s अघि तपाईंको फोनमाथि पहुँच राख्यो" + "%1$s ले %2$s अघि तपाईंका सेन्सरमाथि पहुँच राख्यो" + "%1$s ले %2$s अघि तपाईंको SMS माथि पहुँच राख्यो" + "%1$s ले %2$s अघि तपाईंको भण्डारणमाथि पहुँच राख्यो" + "%1$s ले तपाईंको %2$s माथि पहुँच राखेको छैन" + "%1$s ले तपाईंको शारीरिक क्रियाकलापको डेटामाथि पहुँच राखेको छैन" + "%1$s ले तपाईंको पात्रोमाथि पहुँच राखेको छैन" + "%1$s ले तपाईंको कलका लगमाथि पहुँच राखेको छैन" + "%1$s ले तपाईंको क्यामेरामाथि पहुँच राखेको छैन" + "%1$s ले तपाईंका सम्पर्क ठेगानामाथि पहुँच राखेको छैन" + "%1$s ले तपाईंको स्थानमाथि पहुँच राखेको छैन" + "%1$s ले तपाईंको माइक्रोफोनमाथि पहुँच राखेको छैन" + "%1$s ले तपाईंको फोनमाथि पहुँच राखेको छैन" + "%1$s ले तपाईंका सेन्सरमाथि पहुँच राखेको छैन" + "%1$s ले तपाईंको SMS माथि पहुँच राखेको छैन" + "%1$s ले तपाईंको भण्डारणमाथि पहुँच राखेको छैन" "पछिल्लो पटक पहुँच राखिएको डेटा यो अनुमतिका लागि हाल उपलब्ध छैन" "%1$s का सबै अनुमतिहरू हेर्नुहोस्" "यो अनुमति पाएका सबै अनुप्रयोगहरू हेर्नुहोस्" diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml index 08237f9ea..18ad8b8ea 100644 --- a/res/values-nl/strings.xml +++ b/res/values-nl/strings.xml @@ -145,8 +145,30 @@ "Weigeren" "%1$s-recht" "Toegang tot %1$s voor deze app" - "%1$s heeft %3$s geleden toegang gehad tot je %2$s" - "%1$s heeft geen toegang gehad tot je %2$s" + "%1$s heeft %3$s geleden toegang tot je %2$s gehad" + "%1$s heeft %2$s geleden toegang tot je fysieke activiteit gehad" + "%1$s heeft %2$s geleden toegang tot je agenda gehad" + "%1$s heeft %2$s geleden toegang tot je gesprekkenlijsten gehad" + "%1$s heeft %2$s geleden toegang tot je camera gehad" + "%1$s heeft %2$s geleden toegang tot je contacten gehad" + "%1$s heeft %2$s geleden toegang tot je locatie gehad" + "%1$s heeft %2$s geleden toegang tot je microfoon gehad" + "%1$s heeft %2$s geleden toegang tot je telefoon gehad" + "%1$s heeft %2$s geleden toegang tot je sensoren gehad" + "%1$s heeft %2$s geleden toegang tot je sms gehad" + "%1$s heeft %2$s geleden toegang tot je opslag gehad" + "%1$s heeft geen toegang tot je %2$s gehad" + "%1$s heeft geen toegang tot je fysieke activiteit gehad" + "%1$s heeft geen toegang tot je agenda gehad" + "%1$s heeft geen toegang tot je gesprekkenlijsten gehad" + "%1$s heeft geen toegang tot je camera gehad" + "%1$s heeft geen toegang tot je contacten gehad" + "%1$s heeft geen toegang tot je locatie gehad" + "%1$s heeft geen toegang tot je microfoon gehad" + "%1$s heeft geen toegang tot je telefoon gehad" + "%1$s heeft geen toegang tot je sensoren gehad" + "%1$s heeft geen toegang tot je sms gehad" + "%1$s heeft geen toegang tot je opslag gehad" "Gegevens over laatste toegang zijn momenteel niet beschikbaar voor dit recht" "Alle rechten van %1$s bekijken" "Alle apps met dit recht bekijken" diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml index 0ad37d85d..2ad44033b 100644 --- a/res/values-or/strings.xml +++ b/res/values-or/strings.xml @@ -37,7 +37,7 @@ "ସମସ୍ତ ଅନୁମତି ଅକ୍ଷମ କରାଯାଇଛି" "କୌଣସି ଅନୁମତି ଅକ୍ଷମ କରାଯାଇନାହିଁ" "ଅନୁମତି ଦିଅନ୍ତୁ" - "ସଦାବେଳ ପାଇଁ ଅନୁମତି ଦିଅନ୍ତୁ" + "ସବୁବେଳେ ଅନୁମତି ଦିଅନ୍ତୁ" "ଆପ୍ ବ୍ୟବହାର ବେଳେ କେବଳ ଅନୁମତି ଦିଅନ୍ତୁ" "ସର୍ବଦା ଅନୁମତି ଦିଅନ୍ତୁ" "ଆପ୍ସ" @@ -145,16 +145,38 @@ "ଖାରଜ କରନ୍ତୁ" "%1$s ଅନୁମତି" "ଏହି ଆପ୍‍ ପାଇଁ %1$s ଆକ୍ସେସ୍‌ କରନ୍ତୁ" - "%1$s %3$s ପୂର୍ବରୁ ଆପଣଙ୍କ %2$s ଆକ୍ସେସ୍‍ କରିଥିଲେ" - "%1$s ଆପଣଙ୍କ %2$s ଆକ୍ସେସ୍ କରି ନାହିଁ" - "ଏହି ଅନୁମତି ପାଇଁ ଶେଷ ଆକ୍ସେସ୍ ଡାଟା ବର୍ତ୍ତମାନ ଉପଲବ୍ଧ ନାହିଁ" + "%1$s %3$s ପୂର୍ବରୁ ଆପଣଙ୍କ %2$s ଆକ୍ସେସ୍ କରିଥିଲା" + "%1$s %2$s ପୂର୍ବରୁ ଆପଣଙ୍କ ଶାରୀରିକ କାର୍ଯ୍ୟକଳାପ ଆକ୍ସେସ୍ କରିଥିଲା" + "%1$s %2$s ପୂର୍ବରୁ ଆପଣଙ୍କ କ୍ୟାଲେଣ୍ଡର୍ ଆକ୍ସେସ୍ କରିଥିଲା" + "%1$s %2$s ପୂର୍ବରୁ ଆପଣଙ୍କ କଲ୍ ଲଗ୍ ଆକ୍ସେସ୍ କରିଥିଲା" + "%1$s %2$s ପୂର୍ବରୁ ଆପଣଙ୍କ କ୍ୟାମେରା ଆକ୍ସେସ୍ କରିଥିଲା" + "%1$s %2$s ପୂର୍ବରୁ ଆପଣଙ୍କ ଯୋଗାଯୋଗଗୁଡ଼ିକୁ ଆକ୍ସେସ୍ କରିଥିଲା" + "%1$s %2$s ପୂର୍ବରୁ ଆପଣଙ୍କ ଲୋକେସନ୍ ଆକ୍ସେସ୍ କରିଥିଲା" + "%1$s %2$s ପୂର୍ବରୁ ଆପଣଙ୍କର ମାଇକ୍ରୋଫୋନ୍ ଆକ୍ସେସ୍ କରିଥିଲା" + "%1$s %2$s ପୂର୍ବରୁ ଆପଣଙ୍କ ଫୋନ୍ ଆକ୍ସେସ୍ କରିଥିଲା" + "%1$s %2$s ପୂର୍ବରୁ ଆପଣଙ୍କ ସେନ୍ସର୍ ଆକ୍ସେସ୍ କରିଥିଲା" + "%1$s %2$s ପୂର୍ବରୁ ଆପଣଙ୍କ SMS ଆକ୍ସେସ୍ କରିଥିଲା" + "%1$s %2$s ପୂର୍ବରୁ ଆପଣଙ୍କ ଷ୍ଟୋରେଜ୍ ଆକ୍ସେସ୍ କରିଥିଲା" + "%1$s ଆପଣଙ୍କ %2$s ଆକ୍ସେସ୍ କରି ନାହିଁ" + "%1$s ଆପଣଙ୍କ ଶାରୀରିକ କାର୍ଯ୍ୟକଳାପ ଆକ୍ସେସ୍ କରି ନାହିଁ" + "%1$s ଆପଣଙ୍କ କ୍ୟାଲେଣ୍ଡର୍ ଆକ୍ସେସ୍ କରି ନାହିଁ" + "%1$s ଆପଣଙ୍କ କଲ୍ ଲଗ୍ ଆକ୍ସେସ୍ କରିଥିଲା" + "%1$s ଆପଣଙ୍କ କ୍ୟାମେରା ଆକ୍ସେସ୍ କରି ନାହିଁ" + "%1$s ଆପଣଙ୍କ ଯୋଗାଯୋଗ ଆକ୍ସେସ୍ କରି ନାହିଁ" + "%1$s ଆପଣଙ୍କ ଲୋକେସନ୍ ଆକ୍ସେସ୍ କରି ନାହିଁ" + "%1$s ଆପଣଙ୍କ ମାଇକ୍ରୋଫୋନ୍ ଆକ୍ସେସ୍ କରି ନାହିଁ" + "%1$s ଆପଣଙ୍କ ଫୋନ୍ ଆକ୍ସେସ୍ କରି ନାହିଁ" + "%1$s ଆପଣଙ୍କ ସେନ୍ସର୍ ଆକ୍ସେସ୍ କରି ନାହିଁ" + "%1$s ଆପଣଙ୍କ SMS ଆକ୍ସେସ୍ କରି ନାହିଁ" + "%1$s ଆପଣଙ୍କ ଷ୍ଟୋରେଜ୍ ଆକ୍ସେସ୍ କରି ନାହିଁ" + "ଏହି ଅନୁମତି ପାଇଁ ଗତ ଆକ୍ସେସ୍ ଡାଟା ବର୍ତ୍ତମାନ ଉପଲବ୍ଧ ନାହିଁ" "ସମସ୍ତ %1$s ଅନୁମତିଗୁଡ଼ିକ ଦେଖନ୍ତୁ" "ଏହି ଅନୁମତି ଥିବା ସମସ୍ତ ଆପ୍ସ ଦେଖନ୍ତୁ" - "ଏହି ଅନୁମତି ଥିବା ଆପ୍ସ %1$s କରିପାରିବ" + "ଏହି ଅନୁମତି ଥିବା ଆପ୍ସ %1$s" "ଏହି ଅନୁମତି ଥିବା ଆପ୍ସ ଆପଣଙ୍କର ଶାରୀରିକ କାର୍ଯ୍ୟକଳାପ, ଯେପରିକି ଚାଲିବା, ସାଇକେଲ ଚଲେଇବା, ଗାଡ଼ି ଚଲାଇବା, କେତେ ପାଦ ଚାଲିଲେ ତାହା ଗଣିବା ଏବଂ ଆହୁରି ଅନେକ କିଛି ଆକ୍ସେସ୍ କରିପାରିବ" "ଏହି ଅନୁମତି ଥିବା ଆପ୍ସ ଆପଣଙ୍କର କ୍ୟାଲେଣ୍ଡର୍ ଆକ୍ସେସ୍ କରିପାରିବ" "ଏହି ଅନୁମତି ଥିବା ଆପ୍‌ଗୁଡ଼ିକ ଫୋନ୍‌ କଲ୍ ଲଗ୍ ପଢ଼ିପାରିବେ ଏବଂ ଲେଖିପାରିବେ" - "ଏହି ଅନୁମତି ଥିବା ଆପ୍ସ ଛବି ଏବଂ ରେକର୍ଡ ଭିଡିଓଗୁଡ଼ିକୁ ନେଇ ପାରିବେ" + "ଏହି ଅନୁମତି ଥିବା ଆପ୍ସ ଛବି ନେଇପାରିବେ ଏବଂ ଭିଡିଓ ରେକର୍ଡ କରିପାରିବେ" "ଏହି ଅନୁମତି ଥିବା ଆପ୍ସ ଆପଣଙ୍କର ଯୋଗାଯୋଗଗୁଡ଼ିକୁ ଆକ୍ସେସ୍ କରିପାରିବ" "ଏହି ଅନୁମତି ଥିବା ଆପ୍ସ ଏହି ଡିଭାଇସ୍‌ର ଲୋକେସନ୍‍ ଆକ୍ସେସ୍‍ କରିପାରିବ" "ଏହି ଅନୁମତି ଥିବା ଆପ୍ସ ଅଡିଓ ରେକର୍ଡ କରିପାରିବେ" @@ -225,7 +247,7 @@ "ଆପ୍ସ ଯାହା ଆପଣଙ୍କୁ ଗମ୍ଭୀର ପାଣିପାଗ ଇଭେଣ୍ଟ ଏବଂ ଦୈବ ଦୁର୍ବିପାକ ବିଷୟରେ ଆଲର୍ଟ ପାଇବା ପାଇଁ ଏବଂ ଆପଣ ସାହାଯ୍ୟ ଆବଶ୍ୟକ କରୁଥିବା ସମୟରେ ଅନ୍ୟମାନଙ୍କୁ ଜଣାଇବାକୁ ଦିଏ; ଆପଣଙ୍କୁ ନିଜର ଚିକିତ୍ସା ସୂଚନୀ ରେକର୍ଡ କରିବାକୁ ଦିଏ ଏବଂ ସେହି ରେକର୍ଡକୁ ଜରୁରିକାଳୀନ ସହାୟତା କର୍ମଚାରୀଙ୍କ ପାଇଁ ଆକ୍ସେସ୍ ଯୋଗ୍ୟ କରାଇଥାଏ" "%1$sକୁ ଆପଣଙ୍କର ଡିଫଲ୍ଟ ଜରୁରୀକାଳୀନ ଆପ୍ ଭାବେ ସେଟ୍ କରିବେ କି?" "କୌଣସି ଅନୁମତି ଆବଶ୍ୟକ ନାହିଁ" - "ଡିଫଲ୍ଟ ମୂଳ ଆପ୍" + "ଡିଫଲ୍ଟ୍ ହୋମ୍ ଆପ୍" "ମୂଳ ଆପ୍" "ଯେଉଁ ଆପ୍ସକୁ ସାଧାରଣତଃ ଲଞ୍ଚର୍ କୁହାଯାଏ, ସେହି ଆପ୍ସ ଆପଣଙ୍କର Android ଡିଭାଇସ୍‌ରେ ମୂଳ ସ୍କ୍ରୀନ୍‌କୁ ପ୍ରତିସ୍ଥାପନ କରିଥାଏ ଏବଂ ଆପଣଙ୍କର ଡିଭାଇସ୍‌ର ବିଷୟବସ୍ତୁ ଏବଂ ବୈଶିଷ୍ଟ୍ୟଗୁଡ଼ିକୁ ଆକ୍ସେସ୍ ପ୍ରଦାନ କରିଥାଏ।" "%1$s କୁ ଆପଣଙ୍କ ଡିଫଲ୍ଟ ମୂଳ ଆପ୍ ଭାବରେ ସେଟ୍ କରିବେ କି?" diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml index 6623b06ed..1cf19dab7 100644 --- a/res/values-pa/strings.xml +++ b/res/values-pa/strings.xml @@ -145,8 +145,30 @@ "ਅਸਵੀਕਾਰ ਕਰੋ" "%1$s ਇਜਾਜ਼ਤ" "ਇਸ ਐਪ ਲਈ %1$s ਪਹੁੰਚ" - "%1$s ਨੇ %3$s ਪਹਿਲਾਂ ਤੁਹਾਡੇ %2$s ਤੱਕ ਪਹੁੰਚ ਕੀਤੀ" - "%1$s ਨੇ ਤੁਹਾਡੇ %2$s ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ" + "%1$s ਨੇ %3$s ਪਹਿਲਾਂ ਤੁਹਾਡੇ %2$s ਤੱਕ ਪਹੁੰਚ ਕੀਤੀ" + "%1$s ਨੇ %2$s ਪਹਿਲਾਂ ਤੁਹਾਡੀ ਸਰੀਰਕ ਸਰਗਰਮੀ ਤੱਕ ਪਹੁੰਚ ਕੀਤੀ" + "%1$s ਨੇ %2$s ਪਹਿਲਾਂ ਤੁਹਾਡੇ ਕੈਲੰਡਰ ਤੱਕ ਪਹੁੰਚ ਕੀਤੀ" + "%1$s ਨੇ %2$s ਪਹਿਲਾਂ ਕਾਲ ਲੌਗਾਂ ਤੱਕ ਪਹੁੰਚ ਕੀਤੀ" + "%1$s ਨੇ %2$s ਪਹਿਲਾਂ ਤੁਹਾਡੇ ਕੈਮਰੇ ਤੱਕ ਪਹੁੰਚ ਕੀਤੀ" + "%1$s ਨੇ %2$s ਪਹਿਲਾਂ ਤੁਹਾਡੇ ਸੰਪਰਕਾਂ ਤੱਕ ਪਹੁੰਚ ਕੀਤੀ" + "%1$s ਨੇ %2$s ਪਹਿਲਾਂ ਤੁਹਾਡੇ ਟਿਕਾਣੇ ਤੱਕ ਪਹੁੰਚ ਕੀਤੀ" + "%1$s ਨੇ %2$s ਪਹਿਲਾਂ ਤੁਹਾਡੇ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਤੱਕ ਪਹੁੰਚ ਕੀਤੀ" + "%1$s ਨੇ %2$s ਪਹਿਲਾਂ ਤੁਹਾਡੇ ਫ਼ੋਨ ਤੱਕ ਪਹੁੰਚ ਕੀਤੀ" + "%1$s ਨੇ %2$s ਪਹਿਲਾਂ ਤੁਹਾਡੇ ਸੈਂਸਰਾਂ ਤੱਕ ਪਹੁੰਚ ਕੀਤੀ" + "%1$s ਨੇ %2$s ਪਹਿਲਾਂ ਤੁਹਾਡੇ SMS ਤੱਕ ਪਹੁੰਚ ਕੀਤੀ" + "%1$s ਨੇ %2$s ਪਹਿਲਾਂ ਤੁਹਾਡੀ ਸਟੋਰੇਜ ਤੱਕ ਪਹੁੰਚ ਕੀਤੀ" + "%1$s ਨੇ ਤੁਹਾਡੇ %2$s ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ" + "%1$s ਨੇ ਤੁਹਾਡੀ ਸਰੀਰਕ ਸਰਗਰਮੀ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ" + "%1$s ਨੇ ਤੁਹਾਡੇ ਕੈਲੰਡਰ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ" + "%1$s ਨੇ ਤੁਹਾਡੇ ਕਾਲ ਲੌਗਾਂ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ" + "%1$s ਨੇ ਤੁਹਾਡੇ ਕੈਮਰੇ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ" + "%1$s ਨੇ ਤੁਹਾਡੇ ਸੰਪਰਕਾਂ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ" + "%1$s ਨੇ ਤੁਹਾਡੇ ਟਿਕਾਣੇ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ" + "%1$s ਨੇ ਤੁਹਾਡੇ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ" + "%1$s ਨੇ ਤੁਹਾਡੇ ਫ਼ੋਨ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ" + "%1$s ਨੇ ਤੁਹਾਡੇ ਸੈਂਸਰਾਂ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ" + "%1$s ਨੇ ਤੁਹਾਡੇ SMS ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ" + "%1$s ਨੇ ਤੁਹਾਡੀ ਸਟੋਰੇਜ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ" "ਇਸ ਇਜਾਜ਼ਤ ਲਈ ਪਿਛਲੀ ਵਾਰ ਪਹੁੰਚ ਕੀਤਾ ਡਾਟਾ ਇਸ ਵੇਲੇ ਉਪਲਬਧ ਨਹੀਂ ਹੈ" "%1$s ਦੀਆਂ ਸਾਰੀਆਂ ਇਜਾਜ਼ਤਾਂ ਦੇਖੋ" "ਇਸ ਇਜਾਜ਼ਤ ਵਾਲੀਆਂ ਸਾਰੀਆਂ ਐਪਾਂ ਦੇਖੋ" @@ -237,7 +259,7 @@ "ਕਿਸੇ ਇਜਾਜ਼ਤ ਦੀ ਲੋੜ ਨਹੀਂ ਹੈ" "ਪੂਰਵ-ਨਿਰਧਾਰਤ ਕਾਲਰ ਆਈ.ਡੀ. ਅਤੇ ਸਪੈਮ ਐਪ" "ਕਾਲਰ ਆਈ.ਡੀ. ਅਤੇ ਸਪੈਮ ਐਪ" - "ਐਪਾਂ ਜੋ ਤੁਹਾਨੂੰ ਆਉਣ ਵਾਲੀਆਂ ਕਾਲਾਂ ਦੀ ਪਛਾਣ ਕਰਨ, ਸਪੈਮ ਅਤੇ ਰੋਬੋਕਾਲਾਂ ਬਲਾਕ ਕਰਨ, ਆਣਚਾਹੇ ਨੰਬਰਾਂ ਨੂੰ ਬਲੈਕਲਿਸਟ ਕਰਨ ਅਤੇ ਹੋਰ ਬਹੁਤ ਚੀਜ਼ਾਂ ਕਰਨ ਦਿੰਦੀਆਂ ਹਨ" + "ਐਪਾਂ ਜੋ ਤੁਹਾਨੂੰ ਆਉਣ ਵਾਲੀਆਂ ਕਾਲਾਂ ਦੀ ਪਛਾਣ ਕਰਨ, ਸਪੈਮ ਅਤੇ ਰੋਬੋਕਾਲਾਂ ਬਲਾਕ ਕਰਨ, ਅਣਚਾਹੇ ਨੰਬਰਾਂ ਨੂੰ ਬਲੈਕਲਿਸਟ ਕਰਨ ਅਤੇ ਹੋਰ ਬਹੁਤ ਚੀਜ਼ਾਂ ਕਰਨ ਦਿੰਦੀਆਂ ਹਨ" "ਕੀ %1$s ਨੂੰ ਤੁਹਾਡੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਕਾਲਰ ਆਈ.ਡੀ. ਅਤੇ ਸਪੈਮ ਐਪ ਵਜੋਂ ਸੈੱਟ ਕਰਨਾ ਹੈ?" "ਕਿਸੇ ਇਜਾਜ਼ਤ ਦੀ ਲੋੜ ਨਹੀਂ ਹੈ" "ਮੌਜੂਦਾ ਪੂਰਵ-ਨਿਰਧਾਰਤ" diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml index 4ed20f3ef..e1c80024c 100644 --- a/res/values-pl/strings.xml +++ b/res/values-pl/strings.xml @@ -151,8 +151,30 @@ "Odmów" "%1$s – dostęp" "Dostęp aplikacji do: %1$s" - "Aplikacja %1$s użyła dostępu do: %2$s %3$s temu" - "Aplikacja %1$s nie korzysta z: %2$s" + "Aplikacja %1$s korzystała z: %2$s %3$s temu" + "Aplikacja %1$s korzystała z aktywności fizycznej %2$s temu" + "Aplikacja %1$s korzystała z kalendarza %2$s temu" + "Aplikacja %1$s korzystała z rejestru połączeń %2$s temu" + "Aplikacja %1$s korzystała z aparatu %2$s temu" + "Aplikacja %1$s korzystała z kontaktów %2$s temu" + "Aplikacja %1$s korzystała z lokalizacji %2$s temu" + "Aplikacja %1$s korzystała z mikrofonu %2$s temu" + "Aplikacja %1$s korzystała z telefonu %2$s temu" + "Aplikacja %1$s korzystała z czujników %2$s temu" + "Aplikacja %1$s korzystała z SMS-ów %2$s temu" + "Aplikacja %1$s korzystała z pamięci %2$s temu" + "Aplikacja %1$s nie korzysta z: %2$s" + "Aplikacja %1$s nie korzysta z aktywności fizycznej" + "Aplikacja %1$s nie korzysta z kalendarza" + "Aplikacja %1$s nie korzysta z rejestru połączeń" + "Aplikacja %1$s nie korzysta z aparatu" + "Aplikacja %1$s nie korzysta z kontaktów" + "Aplikacja %1$s nie korzysta z lokalizacji" + "Aplikacja %1$s nie korzysta z mikrofonu" + "Aplikacja %1$s nie korzysta z: telefonu" + "Aplikacja %1$s nie korzysta z czujników" + "Aplikacja %1$s nie korzysta z SMS-ów" + "Aplikacja %1$s nie korzysta z pamięci" "Dane o ostatnich użyciu nie są obecnie dostępne dla tych uprawnień" "Zobacz wszystkie uprawnienia aplikacji %1$s" "Wyświetl wszystkie aplikacje z tymi uprawnieniami" diff --git a/res/values-pt-rBR/strings.xml b/res/values-pt-rBR/strings.xml index f1a95b048..a190a3c59 100644 --- a/res/values-pt-rBR/strings.xml +++ b/res/values-pt-rBR/strings.xml @@ -145,8 +145,30 @@ "Negar" "Permissão de %1$s" "Permitir que este app acesse o app %1$s" - "O app %1$s acessou seu app %2$s %3$s atrás" - "O app %1$s não acessou seu app de %2$s" + "%1$s acessou %2$s%3$s" + "%1$s acessou sua atividade física há %2$s" + "%1$s acessou sua agenda há %2$s" + "%1$s acessou seus registros de chamadas há %2$s" + "%1$s acessou sua câmera há %2$s" + "%1$s acessou seus contatos há %2$s" + "%1$s acessou sua localização há %2$s" + "%1$s acessou seu microfone há %2$s" + "%1$s acessou seu telefone há %2$s" + "%1$s acessou seus sensores há %2$s" + "%1$s acessou seu SMS há %2$s" + "%1$s acessou seu armazenamento há %2$s" + "%1$s não acessou %2$s" + "%1$s não acessou sua atividade física" + "%1$s não acessou sua agenda" + "%1$s não acessou seus registros de chamadas" + "%1$s não acessou sua câmera" + "%1$s não acessou seus contatos" + "%1$s não acessou sua localização" + "%1$s não acessou seu microfone" + "%1$s não acessou seu telefone" + "%1$s não acessou seus sensores" + "%1$s não acessou seu SMS" + "%1$s não acessou seu armazenamento" "Os dados do último acesso não estão disponíveis para essa permissão no momento" "Ver todas as permissões do app %1$s" "Ver todos os apps que têm esta permissão" diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml index 26cbedacb..776667de3 100644 --- a/res/values-pt-rPT/strings.xml +++ b/res/values-pt-rPT/strings.xml @@ -145,8 +145,30 @@ "Recusar" "Autorização de %1$s" "Acesso ao(à) %1$s para esta aplicação." - "A aplicação %1$s acedeu ao(à) %2$s%3$s." - "A aplicação %1$s não acedeu à sua %2$s." + "A aplicação %1$s acedeu à autorização %2$s%3$s." + "A aplicação %1$s acedeu à atividade física há %2$s." + "A aplicação %1$s acedeu ao calendário há %2$s." + "A aplicação %1$s acedeu aos registos de chamadas há %2$s." + "A aplicação %1$s acedeu à câmara há %2$s." + "A aplicação %1$s acedeu aos contactos há %2$s." + "A aplicação %1$s acedeu à localização há %2$s." + "A aplicação %1$s acedeu ao microfone há %2$s." + "A aplicação %1$s acedeu ao telemóvel há %2$s." + "A aplicação %1$s acedeu aos sensores há %2$s." + "A aplicação %1$s acedeu às SMS há %2$s." + "A aplicação %1$s acedeu ao armazenamento há %2$s." + "A aplicação %1$s não acedeu à autorização %2$s." + "A aplicação %1$s não acedeu à atividade física." + "A aplicação %1$s não acedeu ao calendário." + "A aplicação %1$s não acedeu aos registos de chamadas." + "A aplicação %1$s não acedeu à câmara." + "A aplicação %1$s não acedeu aos contactos." + "A aplicação %1$s não acedeu à localização." + "A aplicação %1$s não acedeu ao microfone." + "A aplicação %1$s não acedeu ao telemóvel." + "A aplicação %1$s não acedeu aos sensores." + "A aplicação %1$s não acedeu às SMS." + "A aplicação %1$s não acedeu ao armazenamento." "De momento, os dados do último acesso não estão disponíveis para esta autorização." "Ver todas as autorizações da aplicação %1$s" "Ver todas as aplicações com esta autorização" diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml index f1a95b048..a190a3c59 100644 --- a/res/values-pt/strings.xml +++ b/res/values-pt/strings.xml @@ -145,8 +145,30 @@ "Negar" "Permissão de %1$s" "Permitir que este app acesse o app %1$s" - "O app %1$s acessou seu app %2$s %3$s atrás" - "O app %1$s não acessou seu app de %2$s" + "%1$s acessou %2$s%3$s" + "%1$s acessou sua atividade física há %2$s" + "%1$s acessou sua agenda há %2$s" + "%1$s acessou seus registros de chamadas há %2$s" + "%1$s acessou sua câmera há %2$s" + "%1$s acessou seus contatos há %2$s" + "%1$s acessou sua localização há %2$s" + "%1$s acessou seu microfone há %2$s" + "%1$s acessou seu telefone há %2$s" + "%1$s acessou seus sensores há %2$s" + "%1$s acessou seu SMS há %2$s" + "%1$s acessou seu armazenamento há %2$s" + "%1$s não acessou %2$s" + "%1$s não acessou sua atividade física" + "%1$s não acessou sua agenda" + "%1$s não acessou seus registros de chamadas" + "%1$s não acessou sua câmera" + "%1$s não acessou seus contatos" + "%1$s não acessou sua localização" + "%1$s não acessou seu microfone" + "%1$s não acessou seu telefone" + "%1$s não acessou seus sensores" + "%1$s não acessou seu SMS" + "%1$s não acessou seu armazenamento" "Os dados do último acesso não estão disponíveis para essa permissão no momento" "Ver todas as permissões do app %1$s" "Ver todos os apps que têm esta permissão" diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml index 6845e3fe1..a778cea20 100644 --- a/res/values-ro/strings.xml +++ b/res/values-ro/strings.xml @@ -148,8 +148,30 @@ "Refuzați" "Permisiune %1$s" "Accesul la %1$s pentru această aplicație" - "Aplicația %1$s a accesat %2$s acum %3$s." - "%1$s nu a accesat %2$s" + "Aplicația %1$s a accesat %2$s acum %3$s" + "Aplicația %1$s a accesat activitatea fizică acum %2$s" + "Aplicația %1$s a accesat calendarul acum %2$s" + "Aplicația %1$s a accesat jurnalele de apeluri acum %2$s" + "Aplicația %1$s a accesat camera foto acum %2$s" + "Aplicația %1$s a accesat persoanele de contact acum %2$s" + "Aplicația %1$s a accesat locația acum %2$s" + "Aplicația %1$s a accesat microfonul acum %2$s" + "Aplicația %1$s a accesat telefonul acum %2$s" + "Aplicația %1$s a accesat senzorii acum %2$s" + "Aplicația %1$s a accesat mesajele SMS acum %2$s" + "Aplicația %1$s a accesat spațiul de stocare acum %2$s" + "Aplicația %1$s nu a accesat %2$s" + "Aplicația %1$s nu a accesat activitatea fizică" + "Aplicația %1$s nu a accesat calendarul" + "Aplicația %1$s nu a accesat jurnalele de apeluri" + "Aplicația %1$s nu a accesat camera foto" + "Aplicația %1$s nu a accesat persoanele de contact" + "Aplicația %1$s nu a accesat locația" + "Aplicația %1$s nu a accesat microfonul" + "Aplicația %1$s nu a accesat telefonul" + "Aplicația %1$s nu a accesat senzorii" + "Aplicația %1$s nu a accesat mesajele SMS" + "Aplicația %1$s nu a accesat spațiul de stocare" "Datele ultimei accesări nu sunt disponibile momentan pentru această permisiune" "Vedeți toate permisiunile aplicației %1$s" "Vedeți toate aplicațiile cu această permisiune" diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index 1db9d9176..101920d85 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -151,8 +151,30 @@ "Запретить" "Разрешение \"%1$s\"" "%1$s: доступ для этого приложения" - "Приложение \"%1$s\" использовало разрешение \"%2$s\" %3$s назад." - "Приложение \"%1$s\" не использовало разрешение \"%2$s\"." + "Приложение \"%1$s\" использовало разрешение \"%2$s\" %3$s назад." + "Приложение \"%1$s\" использовало доступ к физ. активности %2$s назад." + "Приложение \"%1$s\" использовало доступ к календарю %2$s назад." + "Приложение \"%1$s\" использовало доступ к списку вызовов %2$s назад." + "Приложение \"%1$s\" использовало доступ к камере %2$s назад." + "Приложение \"%1$s\" использовало доступ к контактам %2$s назад." + "Приложение \"%1$s\" использовало доступ к местоположению %2$s назад." + "Приложение \"%1$s\" использовало доступ к микрофону %2$s назад." + "Приложение \"%1$s\" использовало доступ к телефону %2$s назад." + "Приложение \"%1$s\" использовало доступ к датчикам %2$s назад." + "Приложение \"%1$s\" использовало доступ к SMS %2$s назад." + "Приложение \"%1$s\" использовало доступ к хранилищу %2$s назад." + "Приложение \"%1$s\" не использовало разрешение \"%2$s\"." + "Приложение \"%1$s\" не использовало доступ к физ. активности." + "Приложение \"%1$s\" не использовало доступ к календарю." + "Приложение \"%1$s\" не использовало доступ к списку вызовов." + "Приложение \"%1$s\" не использовало доступ к камере." + "Приложение \"%1$s\" не использовало доступ к контактам." + "Приложение \"%1$s\" не использовало доступ к местоположению." + "Приложение \"%1$s\" не использовало доступ к микрофону." + "Приложение \"%1$s\" не использовало доступ к телефону." + "Приложение \"%1$s\" не использовало доступ к датчикам." + "Приложение \"%1$s\" не использовало доступ к SMS." + "Приложение \"%1$s\" не использовало доступ к хранилищу." "Нет данных о доступе для этого разрешения." "Все разрешения приложения \"%1$s\"" "Все приложения с этим разрешением" diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml index 14ad6f4fd..9ed00dd7c 100644 --- a/res/values-si/strings.xml +++ b/res/values-si/strings.xml @@ -145,8 +145,30 @@ "ප්‍රතික්ෂේප කර." "%1$s අවසරය" "මෙම යෙදුම සඳහා %1$s ප්‍රවේශය" - "%1$s ඔබේ %2$s වෙත %3$sකට පෙර ප්‍රවේශ විය" - "%1$s ඔබේ %2$s වෙත ප්‍රවේශ වී නැත" + "%1$s %3$sකට පෙර ඔබේ %2$s වෙත ප්‍රවේශ විය" + "%1$s %2$s ට පෙර ඔබේ ශාරීරික ක්‍රියාකාරකමට ප්‍රවේශ විය" + "%1$s %2$s ට පෙර ඔබේ දින දර්ශනයට ප්‍රවේශ විය" + "%1$s %2$s ට පෙර ඔබේ ඇමතුම් ලොගවලට ප්‍රවේශ විය" + "%1$s %2$s ට පෙර ඔබේ කැමරාවට ප්‍රවේශ වී නැත" + "%1$s %2$s ට පෙර ඔබේ සම්බන්ධතා වෙත ප්‍රවේශ විය" + "%1$s %2$s ට පෙර ඔබේ ස්ථානයට ප්‍රවේශ විය" + "%1$s %2$s ට පෙර ඔබේ මයික්‍රොෆෝනයට ප්‍රවේශ විය" + "%1$s %2$s ට පෙර ඔබේ දුරකථනයට ප්‍රවේශ විය" + "%1$s %2$s ට පෙර ඔබේ සංවේදකවලට ප්‍රවේශ විය" + "%1$s %2$s ට පෙර ඔබේ කෙටි පණිවුඩ වෙත ප්‍රවේශ විය" + "%1$s %2$s ට පෙර ඔබේ ආචයනයට ප්‍රවේශ විය" + "%1$s ඔබේ %2$s වෙත ප්‍රවේශ වී නැත" + "%1$s ඔබේ ශාරීරික ක්‍රියාකාරකමට ප්‍රවේශ වී නැත" + "%1$s ඔබේ දින දර්ශනයට ප්‍රවේශ වී නැත" + "%1$s ඔබේ ඇමතුම් ලොගවලට ප්‍රවේශ වීනැත" + "%1$s ඔබේ කැමරාවට ප්‍රවේශ වී නැත" + "%1$s ඔබේ සම්බන්ධතා වෙත ප්‍රවේශ වී නැත" + "%1$s ඔබේ ස්ථානයට ප්‍රවේශ වී නැත" + "%1$s ඔබේ මයික්‍රොෆෝනයට ප්‍රවේශ වී නැත" + "%1$s ඔබේ දුරකථනයට ප්‍රවේශ වී නැත" + "%1$s ඔබේ සංවේදකවලට ප්‍රවේශ වී නැත" + "%1$s ඔබේ කෙටි පණිවුඩ වෙත ප්‍රවේශ වී නැත" + "%1$s ඔබේ ආචයනයට ප්‍රවේශ වී නැත" "මෙම අවසරය සඳහා අවසාන ප්‍රවේශ දත්ත දැනට නොමැත" "සියලුම %1$s අවසර බලන්න" "මෙම අවසරය සහිත සියලුම යෙදුම් බලන්න" diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml index 0f2205233..fea8f3dab 100644 --- a/res/values-sk/strings.xml +++ b/res/values-sk/strings.xml @@ -151,8 +151,30 @@ "Zamietnuť" "%1$s: povolenie" "%1$s: prístup pre túto aplikáciu" - "Aplikácia %1$s použila povolenie %2$s pred %3$s" - "Aplikácia %1$s nepoužila povolenie %2$s" + "Aplikácia %1$s použila povolenie %2$s pred %3$s" + "Aplikácia %1$s použila fyzickú aktivitu pred %2$s" + "Aplikácia %1$s použila kalendár pred %2$s" + "Aplikácia %1$s použila denníky hovorov pred %2$s" + "Aplikácia %1$s použila fotoaparát pred %2$s" + "Aplikácia %1$s použila kontakty pred %2$s" + "Aplikácia %1$s použila polohu pred %2$s" + "Aplikácia %1$s použila mikrofón pred %2$s" + "Aplikácia %1$s použila telefón pred %2$s" + "Aplikácia %1$s použila senzory pred %2$s" + "Aplikácia %1$s použila SMS pred %2$s" + "Aplikácia %1$s použila ukladací priestor pred %2$s" + "Aplikácia %1$s nepoužila povolenie %2$s" + "Aplikácia %1$s nepoužila fyzickú aktivitu" + "Aplikácia %1$s nepoužila kalendár" + "Aplikácia %1$s nepoužila denníky hovorov" + "Aplikácia %1$s nepoužila fotoaparát" + "Aplikácia %1$s nepoužila kontakty" + "Aplikácia %1$s nepoužila polohu" + "Aplikácia %1$s nepoužila mikrofón" + "Aplikácia %1$s nepoužila telefón" + "Aplikácia %1$s nepoužila senzory" + "Aplikácia %1$s nepoužila SMS" + "Aplikácia %1$s nepoužila ukladací priestor" "Pre toto povolenie nie sú momentálne k dispozícii údaje o poslednom prístupe" "Zobraziť všetky povolenia aplikácie %1$s" "Zobraziť všetky aplikácie s týmto povolením" diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml index 2d21cb93e..3c040e006 100644 --- a/res/values-sl/strings.xml +++ b/res/values-sl/strings.xml @@ -151,8 +151,30 @@ "Zavrni" "Dovoljenje %1$s" "Dovoljenje »%1$s« za to aplikacijo" - "Aplikacija %1$s je dovoljenje »%2$s« uporabila pred %3$s" - "Aplikacija %1$s ni uporabila dovoljenja »%2$s«" + "Aplikacija %1$s je dovoljenje »%2$s« uporabila pred %3$s" + "Aplikacija %1$s je dostopala do telesne dejavnosti pred %2$s" + "Aplikacija %1$s je dostopala do koledarja pred %2$s" + "Aplikacija %1$s je dostopala do dnevnikov klicev pred %2$s" + "Aplikacija %1$s je dostopala do fotoaparata pred %2$s" + "Aplikacija %1$s je dostopala do stikov pred %2$s" + "Aplikacija %1$s je dostopala do podatkov o lokaciji pred %2$s" + "Aplikacija %1$s je dostopala do mikrofona pred %2$s" + "Aplikacija %1$s je dostopala do telefona pred %2$s" + "Aplikacija %1$s je dostopala do tipal pred %2$s" + "Aplikacija %1$s je dostopala do sporočil SMS pred %2$s" + "Aplikacija %1$s je dostopala do shrambe pred %2$s" + "Aplikacija %1$s ni uporabila dovoljenja »%2$s«" + "Aplikacija %1$s ni dostopala do podatkov o telesni dejavnosti" + "Aplikacija %1$s ni dostopala do koledarja" + "Aplikacija %1$s ni dostopala do dnevnikov klicev" + "Aplikacija %1$s ni dostopala do fotoaparata" + "Aplikacija %1$s ni dostopala do stikov" + "Aplikacija %1$s ni dostopala do podatkov o lokaciji" + "Aplikacija %1$s ni dostopala do mikrofona" + "Aplikacija %1$s ni dostopala do telefona" + "Aplikacija %1$s ni dostopala do tipal" + "Aplikacija %1$s ni dostopala do sporočil SMS" + "Aplikacija %1$s ni dostopala do shrambe" "Podatki o zadnjem dostopu trenutno niso na voljo za to dovoljenje" "Ogled vseh dovoljenj za aplikacijo %1$s" "Ogled vseh aplikacij s tem dovoljenjem" diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml index d959f9c11..f75c70ab8 100644 --- a/res/values-sq/strings.xml +++ b/res/values-sq/strings.xml @@ -145,8 +145,30 @@ "Refuzo" "Autorizim te %1$s" "Qasja te %1$s për këtë aplikacion" - "%1$s pati qasje te %2$s %3$s më parë" - "%1$s nuk ka pasur qasje te %2$s" + "%1$s pati qasje te %2$s %3$s më parë" + "%1$s pati qasje tek aktiviteti yt fizik %2$s më parë" + "%1$s pati qasje te kalendari yt %2$s më parë" + "%1$s pati qasje tek evidencat e telefonatave të tua %2$s më parë" + "%1$s pati qasje te kamera jote %2$s më parë" + "%1$s pati qasje te kontaktet e tua %2$s më parë" + "%1$s pati qasje te vendndodhja jote %2$s më parë" + "%1$s pati qasje te mikrofoni yt %2$s më parë" + "%1$s pati qasje te telefoni yt %2$s më parë" + "%1$s pati qasje te sensorët e tu %2$s më parë" + "%1$s pati qasje te mesazhet e tua SMS %2$s më parë" + "%1$s pati qasje te hapësira jote ruajtëse %2$s më parë" + "%1$s nuk ka pasur qasje te %2$s" + "%1$s nuk ka pasur qasje tek aktiviteti yt fizik" + "%1$s nuk ka pasur qasje te kalendari yt" + "%1$s nuk ka pasur qasje tek evidencat e telefonatave të tua" + "%1$s nuk ka pasur qasje te kamera jote" + "%1$s nuk ka pasur qasje te kontaktet e tua" + "%1$s nuk ka pasur qasje te vendndodhja jote" + "%1$s nuk ka pasur qasje te mikrofoni yt" + "%1$s nuk ka pasur qasje te telefoni yt" + "%1$s nuk ka pasur qasje te sensorët e tu" + "%1$s nuk ka pasur qasje te mesazhet e tua SMS" + "%1$s nuk ka pasur qasje te hapësira jote ruajtëse" "Të dhënat e qasjes së fundit nuk ofrohen aktualisht për këtë leje" "Shiko të gjitha autorizimet e %1$s" "Shiko të gjitha aplikacionet me këtë autorizim" diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml index 555f72b10..1df220ac4 100644 --- a/res/values-sr/strings.xml +++ b/res/values-sr/strings.xml @@ -148,8 +148,30 @@ "Одбиј" "%1$s - дозвола" "Приступ ове апликације функцији „%1$s“" - "Апликација %1$s је приступила функцији „%2$s“ пре %3$s" - "Апликација %1$s није приступила функцији „%2$s“" + "Апликација %1$s је приступила функцији „%2$s“ пре %3$s" + "Апликација %1$s је приступила физичким активностима пре %2$s" + "Апликација %1$s је приступила календару пре %2$s" + "Апликација %1$s је приступила евиденцијама позива пре %2$s" + "Апликација %1$s је приступила камери пре %2$s" + "Апликација је %1$s приступила контактима пре %2$s" + "Апликација %1$s је приступила локацији пре %2$s" + "Апликација %1$s је приступила микрофону пре %2$s" + "Апликација %1$s је приступила телефону пре %2$s" + "Апликација %1$s је приступила сензорима пре %2$s" + "Апликација је %1$s је приступила SMS-овима пре %2$s" + "Апликација %1$s је приступила меморијском простору пре %2$s" + "Апликација %1$s није приступила функцији „%2$s“" + "Апликација %1$s није приступила физичким активностима" + "Апликација %1$s није приступила календару" + "Апликација %1$s није приступила евиденцијама позива" + "Апликација %1$s није приступила камери" + "Апликација %1$s није приступила контактима" + "Апликација %1$s није приступила локацији" + "Апликација %1$sније приступила микрофону" + "Апликација %1$s није приступила телефону" + "Апликација %1$s није приступила сензорима" + "Апликација %1$s није приступила SMS-овима" + "Апликација %1$s није приступила меморијском простору" "Подаци о последњем приступу тренутно нису доступни за ову дозволу" "Прикажи све дозволе (%1$s)" "Прикажи све апликације са овом дозволом" diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml index d7f69e33e..ce381d2b2 100644 --- a/res/values-sv/strings.xml +++ b/res/values-sv/strings.xml @@ -145,8 +145,30 @@ "Neka" "Behörighet till %1$s" "Åtkomst till %1$s för appen" - "%1$s använde din %2$s för %3$s sedan" - "%1$s har inte fått åtkomst till %2$s" + "%1$s använde behörigheten %2$s för %3$s sedan" + "%1$s använde data om fysisk aktivitet för %2$s sedan" + "%1$s använde kalendern för %2$s sedan" + "%1$s använde samtalshistoriken för %2$s sedan" + "%1$s använde kameran för %2$s sedan" + "%1$s använde kontaktbehörigheten för %2$s sedan" + "%1$s använde platsbehörigheten för %2$s sedan" + "%1$s använde mikrofonen för %2$s sedan" + "%1$s använde telefonen för %2$s sedan" + "%1$s använde sensorerna för %2$s sedan" + "%1$s använde sms-behörigheten för %2$s sedan" + "%1$s använde lagringsutrymmet för %2$s sedan" + "%1$s har inte använt behörigheten %2$s" + "%1$s har inte använt data om fysisk aktivitet" + "%1$s har inte använt kalendern" + "%1$s har inte använt samtalshistoriken" + "%1$s har inte använt kameran" + "%1$s har inte använt kontaktbehörigheten" + "%1$s har inte använt platsbehörigheten" + "%1$s har inte använt mikrofonen" + "%1$s har inte använt telefonen" + "%1$s har inte använt några sensorer" + "%1$s har inte använt sms-behörigheten" + "%1$s har inte använt lagringsutrymmet" "Det finns just nu ingen tillgänglig data om senaste användningen för den här behörigheten" "Visa alla behörigheter för %1$s" "Visa alla appar med den här behörigheten" diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml index 04ec3e5c3..f5982fe7b 100644 --- a/res/values-sw/strings.xml +++ b/res/values-sw/strings.xml @@ -145,8 +145,30 @@ "Kataa" "Ruhusa ya %1$s" "Idhini ya %1$s kufikia programu hii" - "%1$s imefikia %2$s %3$s zilizopita" - "%1$s haijafikia %2$s yako" + "%1$s ilifikia %2$s yako %3$s zilizopita" + "%1$s ilifikia shughuli zako za kimwili %2$s zilizopita" + "%1$s ilifikia kalenda yako %2$s zilizopita" + "%1$s ilifikia rekodi yako ya nambari za simu %2$s zilizopita" + "%1$s ilifikia kamera yako %2$s zilizopita" + "%1$s ilifikia anwani zako %2$s zilizopita" + "%1$s ilifikia maelezo ya mahali ulipo %2$s zilizopita" + "%1$s ilifikia maikrofoni yako %2$szilizopita" + "%1$s ilifikia simu yako %2$s zilizopita" + "%1$s ilifikia vitambuzi vyako %2$s zilizopita" + "%1$s ilifikia SMS zako %2$s zilizopita" + "%1$s ilifikia nafasi yako ya hifadhi %2$s zilizopita" + "%1$s haijafikia %2$s yako" + "%1$s haijafikia shughuli zako za kimwili" + "%1$s haijafikia kalenda yako" + "%1$s haijafikia rekodi yako ya nambari za simu" + "%1$s haijafikia kamera yako" + "%1$s haijafikia anwani zako" + "%1$s haijafikia maelezo ya mahali ulipo" + "%1$s haijafikia maikrofoni yako" + "%1$s haijafikia simu yako" + "%1$s haijafikia vitambuzi vyako" + "%1$s haijafikia SMS zako" + "%1$s haijafikia nafasi yako ya hifadhi" "Data ya mara ya mwisho ambayo ruhusa hii ilifikiwa haipatikani kwa sasa" "Angalia ruhusa zote za %1$s" "Angalia programu zote zenye ruhusa hii" diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml index b552bc13d..31fa4d37f 100644 --- a/res/values-ta/strings.xml +++ b/res/values-ta/strings.xml @@ -145,8 +145,30 @@ "நிராகரி" "%1$s என்பதற்கான அனுமதி" "இந்த ஆப்ஸிற்கு %1$s அணுகல்" - "%3$s முன்பு %1$s ஆப்ஸ் உங்கள் %2$s அணுகலைப் பயன்படுத்தியது" - "%1$s உங்கள் %2$s அணுகலைப் பயன்படுத்தவில்லை" + "%3$s முன்பு %1$s ஆப்ஸ் உங்கள் %2$s அணுகலைப் பயன்படுத்தியது" + "%2$s முன்பு %1$s உடல் செயல்பாடுகளுக்கான அணுகலைப் பயன்படுத்தியது" + "%2$s முன்பு %1$s உங்கள் கேலெண்டருக்கான அணுகலைப் பயன்படுத்தியது" + "%2$s முன்பு %1$s அழைப்புப் பதிவுகளுக்கான அணுகலைப் பயன்படுத்தியது" + "%2$s முன்பு%1$s உங்கள் கேமராவிற்கான அணுகலைப் பயன்படுத்தியது" + "%2$s முன்பு %1$s உங்கள் தொடர்புகளுக்கான அணுகலைப் பயன்படுத்தியது" + "%2$s முன்பு %1$s உங்கள் இருப்பிட அணுகலைப் பயன்படுத்தியது" + "%2$s முன்பு %1$s உங்கள் மைக்ரோஃபோனுக்கான அணுகலைப் பயன்படுத்தியது" + "%2$s முன்பு %1$s உங்கள் மொபைலுக்கான அணுகலைப் பயன்படுத்தியது" + "%2$s முன்பு %1$s உங்கள் சென்சார்களுக்கான அணுகலைப் பயன்படுத்தியது" + "%2$s முன்பு %1$s உங்கள் SMSஸைப் பயன்படுத்தியது" + "%2$s முன்பு %1$s உங்கள் சேமிப்பக அணுகலைப் பயன்படுத்தியது" + "%1$s உங்கள் %2$s அணுகலைப் பயன்படுத்தவில்லை" + "%1$s உங்கள் உடல் செயல்பாடுகளுக்கான அணுகலைப் பயன்படுத்தவில்லை" + "%1$s உங்கள் கேலெண்டருக்கான அணுகலைப் பயன்படுத்தவில்லை" + "%1$s உங்கள் அழைப்புப் பதிவுகளுக்கான அணுகலைப் பயன்படுத்தவில்லை" + "%1$s உங்கள் கேமராவிற்கான அணுகலைப் பயன்படுத்தவில்லை" + "%1$s உங்கள் தொடர்புகளுக்கான அணுகலைப் பயன்படுத்தவில்லை" + "%1$s உங்கள் இருப்பிட அணுகலைப் பயன்படுத்தவில்லை" + "%1$s உங்கள் மைக்ரோஃபோனுக்கான அணுகலைப் பயன்படுத்தவில்லை" + "%1$s உங்கள் மொபைலுக்கான அணுகலைப் பயன்படுத்தவில்லை" + "%1$s உங்கள் சென்சார்களுக்கான அணுகலைப் பயன்படுத்தவில்லை" + "%1$s உங்கள் SMSஸிற்கான அணுகலைப் பயன்படுத்தவில்லை" + "%1$s உங்கள் சேமிப்பக அணுகலைப் பயன்படுத்தவில்லை" "இந்த அனுமதியில் கடைசியாக அணுகிய தரவு தற்போது கிடைக்கவில்லை" "அனைத்து %1$s அனுமதிகளையும் காட்டு" "இந்த அனுமதியைக் கொண்டுள்ள அனைத்து ஆப்ஸையும் காட்டு" diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml index d99cad57e..266be2651 100644 --- a/res/values-te/strings.xml +++ b/res/values-te/strings.xml @@ -145,12 +145,34 @@ "తిరస్కరించు" "%1$s అనుమతి" "ఈ యాప్ కోసం %1$s యాక్సెస్" - "%1$s మీ %2$sను %3$s కింద‌ట‌ యాక్సెస్ చేసింది" - "%1$s మీ %2$sను యాక్సెస్ చేయలేదు" + "%1$s మీ %2$sను %3$s క్రితం యాక్సెస్ చేసింది" + "%2$s క్రితం %1$s మీ భౌతిక కార్యకలాపాన్ని యాక్సెస్ చేసింది" + "%2$s క్రితం %1$s మీ క్యాలెండర్‌ను యాక్సెస్ చేసింది" + "%2$s క్రితం %1$s మీ కాల్ లాగ్‌లను యాక్సెస్ చేసింది" + "%2$s క్రితం %1$s మీ కెమెరాను యాక్సెస్ చేసింది" + "%2$s క్రితం %1$s మీ పరిచయాలను యాక్సెస్ చేసింది" + "%2$s క్రితం %1$s మీ స్థానాన్ని యాక్సెస్ చేసింది" + "%2$s క్రితం %1$s మీ మైక్రోఫోన్‌ను యాక్సెస్ చేసింది" + "%2$s క్రితం %1$s మీ ఫోన్‌ను యాక్సెస్ చేసింది" + "%2$s క్రితం %1$s మీ సెన్సార్‌లను యాక్సెస్ చేసింది" + "%2$s క్రితం %1$s మీ SMSను యాక్సెస్ చేసింది" + "%2$s క్రితం %1$s మీ నిల్వను యాక్సెస్ చేసింది" + "%1$s మీ %2$sను యాక్సెస్ చేయలేదు" + "%1$s మీ భౌతిక కార్యాకలాపాన్ని యాక్సెస్ చేయలేదు" + "%1$s మీ క్యాలెండర్‌ను యాక్సెస్ చేయలేదు" + "%1$s మీ కాల్ లాగ్‌లను యాక్సెస్ చేయలేదు" + "%1$s మీ కెమెరాను యాక్సెస్ చేయలేదు" + "%1$s మీ పరిచయాలను యాక్సెస్ చేయలేదు" + "%1$s మీ స్థానాన్ని యాక్సెస్ చేయలేదు" + "%1$s మీ మైక్రోఫోన్‌ను యాక్సెస్ చేయలేదు" + "%1$s మీ ఫోన్‌ను యాక్సెస్ చేయలేదు" + "%1$s మీ సెన్సార్‌లను యాక్సెస్ చేయలేదు" + "%1$s మీ SMSను యాక్సెస్ చేయలేదు" + "%1$s మీ నిల్వను యాక్సెస్ చేయలేదు" "ఈ అనుమతి కోసం చివరిగా యాక్సెస్ చేసిన డేటా ప్రస్తుతం అందుబాటులో లేదు" - "అన్ని %1$s అనుమతులను చూడండి" + "అన్ని \'%1$s\' అనుమతులను చూడండి" "ఈ అనుమతి ఉన్న అన్ని యాప్‌లను చూడండి" - "ఈ అనుమతి ఉన్న యాప్‌లు %1$s చేయగలవు" + "ఈ యాప్‌ల‌కు ఈ అనుమ‌తి ఇస్తుంది- %1$s" "ఈ అనుమతి ఉన్న యాప్‌లు వాకింగ్, బైకింగ్, డ్రైవింగ్, అడుగుల గణన వంటి మీ భౌతిక కార్యాకలాపాన్ని ఇంకా మరిన్నింటిని యాక్సెస్ చేయగలవు" "ఈ అనుమతి ఉన్న యాప్‌లు మీ క్యాలెండర్‌ను యాక్సెస్ చేయగలవు" "ఈ అనుమతి ఉన్న యాప్‍‌లు ఫోన్ కాల్ లాగ్‌ను చదవగలుగుతాయి, దానిలో రాయగలుగుతాయి" @@ -193,7 +215,7 @@ "యాప్ వినియోగంలో ఉన్నప్పుడు మాత్రమే" "అనుమతులు ఏవీ ఇవ్వలేదు" "అన్ని అనుమతులు ఇచ్చారు" - "ఏ యాప్‌కి ఇవ్వలేదు" + "ఏ యాప్‌న‌కు ఇవ్వలేదు" "ఏ యాప్‌ను నిరాక‌రించ‌లేదు" "సెట్టింగ్‌లు" "%s మీ పరికరానికి పూర్తి యాక్సెస్ కలిగి ఉంది" @@ -227,7 +249,7 @@ "అనుమతులు ఇవ్వనవసరం లేదు" "డిఫాల్ట్ హోమ్ యాప్" "హోమ్ యాప్" - "మీ Android పరికరంలో హోమ్ స్క్రీన్‌లను భర్తీ చేయగల, అలాగే మీకు మీ పరికరం కంటెంట్‌లు, ఫీచర్‌లకు యాక్సెస్ అందించగల యాప్‌లు, ఎక్కువగా లాంచర్‌లు అని పిలువబడేవి" + "మీ Android పరికరంలో హోమ్ స్క్రీన్‌లను భర్తీ చేయగల, మీ పరికరం కంటెంట్‌లు, ఫీచర్‌లకు యాక్సెస్ ఇవ్వ‌గల యాప్‌లు. వీటిని త‌ర‌చుగా లాంచర్‌లు అని పిలుస్తారు" "%1$sను మీ డిఫాల్ట్ హోమ్ యాప్‌గా సెట్ చేయాలా?" "అనుమతులు ఇవ్వనవసరం లేదు" "డిఫాల్ట్ కాల్ మళ్లింపు యాప్" diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml index 5b9928cec..690625f85 100644 --- a/res/values-th/strings.xml +++ b/res/values-th/strings.xml @@ -145,8 +145,30 @@ "ปฏิเสธ" "สิทธิ์เกี่ยวกับ%1$s" "สิทธิ์การเข้าถึง%1$sสำหรับแอปนี้" - "%1$s เข้าถึง%2$sของคุณเมื่อ %3$sที่ผ่านมา" - "%1$s ไม่ได้เข้าถึง%2$sของคุณ" + "%1$s เข้าถึง%2$sเมื่อ %3$sที่ผ่านมา" + "%1$s เข้าถึงกิจกรรมการเคลื่อนไหวร่างกายเมื่อ %2$sที่ผ่านมา" + "%1$s เข้าถึงปฏิทินเมื่อ %2$sที่ผ่านมา" + "%1$s เข้าถึงประวัติการโทรเมื่อ %2$sที่ผ่านมา" + "%1$s เข้าถึงกล้องเมื่อ %2$sที่ผ่านมา" + "%1$s เข้าถึงรายชื่อติดต่อเมื่อ %2$sที่ผ่านมา" + "%1$s เข้าถึงตำแหน่งของคุณเมื่อ %2$sที่ผ่านมา" + "%1$s เข้าถึงไมโครโฟนเมื่อ %2$sที่ผ่านมา" + "%1$s เข้าถึงโทรศัพท์เมื่อ %2$sที่ผ่านมา" + "%1$s เข้าถึงเซ็นเซอร์เมื่อ %2$sที่ผ่านมา" + "%1$s เข้าถึง SMS เมื่อ %2$sที่ผ่านมา" + "%1$s เข้าถึงพื้นที่เก็บข้อมูลเมื่อ %2$sที่ผ่านมา" + "%1$s ไม่ได้เข้าถึง%2$s" + "%1$s ไม่ได้เข้าถึงกิจกรรมการเคลื่อนไหวร่างกาย" + "%1$s ไม่ได้เข้าถึงปฏิทิน" + "%1$s ไม่ได้เข้าถึงประวัติการโทร" + "%1$s ไม่ได้เข้าถึงกล้อง" + "%1$s ไม่ได้เข้าถึงรายชื่อติดต่อ" + "%1$s ไม่ได้เข้าถึงตำแหน่งของคุณ" + "%1$s ไม่ได้เข้าถึงไมโครโฟน" + "%1$s ไม่ได้เข้าถึงโทรศัพท์" + "%1$s ไม่ได้เข้าถึงเซ็นเซอร์" + "%1$s ไม่ได้เข้าถึง SMS" + "%1$s ไม่ได้เข้าถึงพื้นที่เก็บข้อมูล" "ขณะนี้ข้อมูลการเข้าถึงล่าสุดไม่พร้อมใช้งานสำหรับสิทธิ์นี้" "ดูสิทธิ์ทั้งหมดของ %1$s" "ดูแอปทั้งหมดที่มีสิทธิ์นี้" diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml index c670e8ee6..db21cb88a 100644 --- a/res/values-tl/strings.xml +++ b/res/values-tl/strings.xml @@ -145,8 +145,30 @@ "Tanggihan" "%1$s na pahintulot" "access sa %1$s para sa app na ito" - "Na-access ng %1$s ang iyong %2$s %3$s ang nakalipas" - "Hindi na-access ng %1$s ang iyong %2$s" + "Na-access ng %1$s ang iyong %2$s %3$s ang nakalipas" + "Na-access ng %1$s ang iyong pisikal na aktibidad %2$s na ang nakalipas" + "Na-access ng %1$s ang iyong kalendaryo %2$s na ang nakalipas" + "Na-access ng %1$s ang iyong mga log ng tawag %2$s na ang nakalipas" + "Na-access ng %1$s ang iyong camera %2$s na ang nakalipas" + "Na-access ng %1$s ang iyong mga contact %2$s na ang nakalipas" + "Na-access ng %1$s ang iyong lokasyon %2$s na ang nakalipas" + "Na-access ng %1$s ang iyong mikropono %2$s na ang nakalipas" + "Na-access ng %1$s ang iyong telepono %2$s na ang nakalipas" + "Na-access ng %1$s ang iyong mga sensor %2$s na ang nakalipas" + "Na-access ng %1$s ang iyong SMS %2$s na ang nakalipas" + "Na-access ng %1$s ang iyong storage %2$s na ang nakalipas" + "Hindi na-access ng %1$s ang iyong %2$s" + "Hindi na-access ng %1$s ang iyong pisikal na aktibidad" + "Hindi na-access ng %1$s ang iyong kalendaryo" + "Hindi na-access ng %1$s ang iyong mga log ng tawag" + "Hindi na-access ng %1$s ang iyong camera" + "Hindi na-access ng %1$s ang iyong mga contact" + "Hindi na-access ng %1$s ang iyong lokasyon" + "Hindi na-access ng %1$s ang iyong mikropono" + "Hindi na-access ng %1$s ang iyong telepono" + "Hindi na-access ng %1$s ang iyong mga sensor" + "Hindi na-access ng %1$s ang iyong SMS" + "Hindi na-access ng %1$s ang iyong storage" "Kasalukuyang hindi available ang data ng huling pag-access para sa pahintulot na ito" "Tingnan ang lahat ng pahintulot ng %1$s" "Tingnan ang lahat ng app na may ganitong pahintulot" diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml index 950e1d004..54bcd82b6 100644 --- a/res/values-tr/strings.xml +++ b/res/values-tr/strings.xml @@ -145,8 +145,30 @@ "Reddet" "%1$s izni" "Bu uygulamaya %1$s erişimi" - "%1$s %3$s önce cihazınızın %2$s iznine erişti" - "%1$s, %2$s izninize erişmedi" + "%1$s %3$s önce cihazınızın %2$s iznine erişti" + "%1$s, %2$s önce fiziksel aktivitenize erişti" + "%1$s, %2$s önce takviminize erişti" + "%1$s, %2$s önce çağrı kaydınıza erişti" + "%1$s, %2$s önce kameranıza erişti" + "%1$s, %2$s önce kişilerinize erişti" + "%1$s, %2$s önce konumunuza erişti" + "%1$s, %2$s önce mikrofonunuza erişti" + "%1$s, %2$s önce telefonunuza erişti" + "%1$s, %2$s önce sensörlerinize erişti" + "%1$s, %2$s önce SMS\'inize erişti" + "%1$s, %2$s önce depolama alanınıza erişti" + "%1$s, %2$s izninize erişmedi" + "%1$s, fiziksel aktivitenize erişmedi" + "%1$s, takviminize erişmedi" + "%1$s, çağrı kayıtlarınıza erişmedi" + "%1$s, kameranıza erişmedi" + "%1$s, kişilerinize erişmedi" + "%1$s, konumunuza erişmedi" + "%1$s, mikrofonunuza erişmedi" + "%1$s, telefonunuza erişmedi" + "%1$s, sensörlerinize erişmedi" + "%1$s, SMS\'inize erişmedi" + "%1$s, depolama alanınıza erişmedi" "Son erişim verisi şu anda bu izin için yok" "Tüm %1$s izinlerini göster" "Bu izne sahip tüm uygulamaları göster" diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml index 63d45b492..1cfcf88fb 100644 --- a/res/values-uk/strings.xml +++ b/res/values-uk/strings.xml @@ -151,8 +151,30 @@ "Заборонити" "Дозвіл – %1$s" "%1$s: доступ для цього додатка" - "Додаток %1$s отримав доступ до даних (%2$s) %3$s тому" - "Додаток %1$s не отримував доступу до даних (%2$s)" + "Додаток %1$s отримав доступ до даних (%2$s) %3$s тому" + "Додаток %1$s отримав доступ до даних про фіз. активність %2$s тому" + "Додаток %1$s отримав доступ до календаря %2$s тому" + "Додаток %1$s отримав доступ до журналу викликів %2$s тому" + "Додаток %1$s отримав доступ до камери %2$s тому" + "Додаток %1$s отримав доступ до контактів %2$s тому" + "Додаток %1$s отримав доступ до геоданих %2$s тому" + "Додаток %1$s отримав доступ до мікрофона %2$s тому" + "Додаток %1$s отримав доступ до телефона %2$s тому" + "Додаток %1$s отримав доступ до датчиків %2$s тому" + "Додаток %1$s отримав доступ до SMS %2$s тому" + "Додаток %1$s отримав доступ до пам’яті %2$s тому" + "Додаток %1$s не отримував доступу до даних (%2$s)" + "Додаток %1$s не отримував доступу до даних про фіз. активність" + "Додаток %1$s не отримував доступу до календаря" + "Додаток %1$s не отримував доступу до журналу викликів" + "Додаток %1$s не отримував доступу до камери" + "Додаток %1$s не отримував доступу до контактів" + "Додаток %1$s не отримував доступу до геоданих" + "Додаток %1$s не отримував доступу до мікрофона" + "Додаток %1$s не отримував доступу до телефона" + "Додаток %1$s не отримував доступу до датчиків" + "Додаток %1$s не отримував доступу до SMS" + "Додаток %1$s не отримував доступу до пам’яті" "З цим дозволом не можна переглядати дані про останні сеанси доступу" "Переглянути всі дозволи додатка %1$s" "Переглянути всі додатки з цим дозволом" diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml index 7c4d20370..31dbe9562 100644 --- a/res/values-ur/strings.xml +++ b/res/values-ur/strings.xml @@ -145,8 +145,30 @@ "مسترد کریں" "%1$s کی اجازت" "%1$s اس ایپ کے لیے رسائی" - "%1$s نے %3$s پہلے آپ کی %2$s تک رسائی حاصل کی" - "%1$s نے آپ کی %2$s تک رسائی حاصل نہیں کی ہے" + "%1$s نے %3$s پہلے آپ کے %2$s تک رسائی حاصل کی ہے" + "%1$s نے %2$s پہلے آپ کی جسمانی سرگرمی تک رسائی حاصل کی ہے" + "%1$s نے %2$s پہلے آپ کے کیلنڈر تک رسائی حاصل کی ہے" + "%1$s نے %2$s پہلے آپ کی کال لاگز تک رسائی حاصل کی ہے" + "%1$s نے %2$s پہلے آپ کے کیمرے تک رسائی حاصل کی ہے" + "%1$s نے %2$s پہلے آپ کے رابطوں تک رسائی حاصل کی ہے" + "%1$s نے %2$s پہلے آپ کے مقام تک رسائی حاصل کی ہے" + "%1$s نے %2$s پہلے آپ کے مائیکروفون تک رسائی حاصل کی ہے" + "%1$s نے %2$s پہلے آپ کے فون تک رسائی حاصل کی ہے" + "%1$s نے %2$s پہلے آپ کے سینسرز تک رسائی حاصل کی ہے" + "‏%1$s نے %2$s پہلے آپ کے SMS تک رسائی حاصل کی ہے" + "%1$s نے %2$s پہلے آپ کی اسٹوریج تک رسائی حاصل کی ہے" + "%1$s نے آپ کے %2$s تک رسائی حاصل نہیں کی ہے" + "%1$s نے آپ کی جسمانی سرگرمی تک رسائی حاصل نہیں کی ہے" + "%1$s نے آپ کے کیلنڈر تک رسائی حاصل نہیں کی ہے" + "%1$s نے آپ کی کال لاگز تک رسائی حاصل نہیں کی ہے" + "%1$s نے آپ کے کیمرے تک رسائی حاصل نہیں کی ہے" + "%1$s نے آپ کے رابطوں تک رسائی حاصل نہیں کی ہے" + "%1$s نے آپ کے مقام تک رسائی حاصل نہیں کی ہے" + "%1$s نے آپ کے مائیکروفون تک رسائی حاصل نہیں کی ہے" + "%1$s نے آپ کے فون تک رسائی حاصل نہیں کی ہے" + "%1$s نے آپ کے سینسرز تک رسائی حاصل نہیں کی ہے" + "‏%1$s نے آپ کے SMS تک رسائی حاصل نہیں کی ہے" + "%1$s نے آپ کی اسٹوریج تک رسائی حاصل نہیں کی ہے" "آخر بار رسائی کرنے کا ڈیٹا اس اجازت کے لیے اس وقت دستیاب نہیں ہے" "%1$s کی سبھی اجازتیں دیکھیں" "اس اجازت والی سبھی ایپس دیکھیں" diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml index 175e9203d..374e0b35d 100644 --- a/res/values-uz/strings.xml +++ b/res/values-uz/strings.xml @@ -145,8 +145,30 @@ "Rad etish" "%1$s ruxsati" "%1$s: bu ilova uchun ruxsat" - "%1$s %3$s oldin %2$s ruxsatidan foydalandi" - "%1$s ilovasi uchun %2$s ruxsati berilmagan" + "%1$s %3$s oldin %2$s ruxsatidan foydalandi" + "%1$s %2$s oldin jismoniy faoliyatingiz axborotidan foydalandi" + "%1$s %2$s oldin taqvimingizdan foydalandi" + "%1$s %2$s oldin chaqiruvlar jurnalidan foydalandi" + "%1$s %2$s oldin kameradan foydalandi" + "%1$s %2$s oldin kontaktlaringizga kirdi" + "%1$s %2$s oldin joylashuvingiz haqidagi axborotga kirdi" + "%1$s %2$s oldin mikrofondan foydalandi" + "%1$s %2$s oldin telefoningizga kirdi" + "%1$s %2$s oldin sensorlardan foydalandi" + "%1$s %2$s oldin SMS xabarlaringizga kirdi" + "%1$s %2$s oldin xotiradan foydalandi" + "%1$s %2$s ruxsatidan foydalanmadi" + "%1$s jismoniy faoliyatingiz axborotiga kirmadi" + "%1$s taqvimdan foydalanmadi" + "%1$s chaqiruvlar jurnalini ochmadi" + "%1$s kamerangizdan foydalanmadi" + "%1$s kontaktlaringizga kirmadi" + "%1$s joylashuvingiz haqidagi axborotga kirmadi" + "%1$s mikrofondan foydalanmadi" + "%1$s telefoningizdan foydalanmadi" + "%1$s sensorlardan foydalanmadi" + "%1$s SMS xabarlaringizga kirmadi" + "%1$s xotiradan foydalanmadi" "Oxirgi kirilgan axborotlar bu ruxsatnomada mavjud emas" "%1$s uchun berilgan barcha ruxsatlar" "Bu ruxsatga ega barcha ilovalar" diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml index ca6107679..614d20502 100644 --- a/res/values-vi/strings.xml +++ b/res/values-vi/strings.xml @@ -145,8 +145,30 @@ "Từ chối" "Quyền %1$s" "Quyền truy cập %1$s cho ứng dụng này" - "%1$s đã truy cập vào %2$s %3$s trước" - "%1$s chưa truy cập vào %2$s của bạn" + "%1$s đã truy cập vào %2$s của bạn %3$s trước" + "%1$s đã truy cập vào hoạt động thể chất của bạn %2$s trước" + "%1$s đã truy cập vào lịch của bạn %2$s trước" + "%1$s đã truy cập vào nhật ký cuộc gọi của bạn %2$s trước" + "%1$s đã truy cập vào máy ảnh của bạn %2$s trước" + "%1$s đã truy cập vào danh bạ của bạn %2$s trước" + "%1$s đã truy cập vào vị trí của bạn %2$s trước" + "%1$s đã truy cập vào micrô của bạn %2$s trước" + "%1$s đã truy cập vào điện thoại của bạn %2$s trước" + "%1$s đã truy cập vào cảm biến của bạn %2$s trước" + "%1$s đã truy cập vào SMS của bạn %2$s trước" + "%1$s đã truy cập vào bộ nhớ của bạn %2$s trước" + "%1$s chưa truy cập vào %2$s của bạn" + "%1$s chưa truy cập vào hoạt động thể chất của bạn" + "%1$s chưa truy cập vào lịch của bạn" + "%1$s chưa truy cập vào nhật ký cuộc gọi của bạn" + "%1$s chưa truy cập vào máy ảnh của bạn" + "%1$s chưa truy cập vào danh bạ của bạn" + "%1$s chưa truy cập vào vị trí của bạn" + "%1$s chưa truy cập vào micrô của bạn" + "%1$s chưa truy cập vào điện thoại của bạn" + "%1$s chưa truy cập vào cảm biến của bạn" + "%1$s chưa truy cập vào SMS của bạn" + "%1$s chưa truy cập vào bộ nhớ của bạn" "Dữ liệu về lần truy cập gần đây nhất hiện không có sẵn cho quyền này" "Xem tất cả các quyền của %1$s" "Xem tất cả ứng dụng có quyền này" diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml index 5d17990d9..219ad130d 100644 --- a/res/values-zh-rCN/strings.xml +++ b/res/values-zh-rCN/strings.xml @@ -145,8 +145,30 @@ "拒绝" "%1$s权限" "是否允许这个应用访问%1$s" - "%1$s %3$s前访问过您的%2$s" - "%1$s尚未访问您的%2$s" + "%1$s %3$s前访问过您的%2$s" + "%1$s %2$s前访问过您的健身运动" + "%1$s %2$s前访问过您的日历" + "%1$s %2$s前访问过您的通话记录" + "%1$s %2$s前访问过您的相机" + "%1$s %2$s前访问过您的通讯录" + "%1$s %2$s前访问过您的位置信息" + "%1$s %2$s前访问过您的麦克风" + "%1$s %2$s前访问过您的手机" + "%1$s %2$s前访问过您的传感器" + "%1$s %2$s前访问过您的短信" + "%1$s %2$s前访问过您的存储空间" + "%1$s尚未访问您的%2$s" + "%1$s尚未访问您的健身运动" + "%1$s尚未访问您的日历" + "%1$s尚未访问您的通话记录" + "%1$s尚未访问您的相机" + "%1$s尚未访问您的通讯录" + "%1$s尚未访问您的位置信息" + "%1$s尚未访问您的麦克风" + "%1$s尚未访问您的手机" + "%1$s尚未访问您的传感器" + "%1$s尚未访问您的短信" + "%1$s尚未访问您的存储空间" "目前无法提供此权限的上次访问数据" "查看%1$s的所有权限" "查看具有此权限的所有应用" diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml index 91de918fe..6baa78fbb 100644 --- a/res/values-zh-rHK/strings.xml +++ b/res/values-zh-rHK/strings.xml @@ -105,7 +105,7 @@ "沒有應用程式使用要求的權限" "任意時段內的最近一次存取" "過去 7 天內的近期存取" - "過去 24 小時內的最近一次存取" + "過去 24 小時內的最近存取" "過去 1 小時內的最近一次存取" "過去 15 分鐘內的最近一次存取" "過去 1 分鐘內的最近一次存取" @@ -145,8 +145,30 @@ "拒絕" "%1$s權限" "這個應用程式的%1$s存取權" - "「%1$s」於 %3$s前存取了您的%2$s" - "「%1$s」沒有存取%2$s" + "「%1$s」於 %3$s前存取了您的%2$s" + "「%1$s」於 %2$s前存取了您的運動資料" + "「%1$s」於 %2$s前存取了您的日曆" + "「%1$s」於 %2$s前存取了您的通話記錄" + "「%1$s」於 %2$s前存取了您的相機" + "「%1$s」於 %2$s前存取了您的聯絡人" + "「%1$s」於 %2$s前存取了您的位置" + "「%1$s」於 %2$s前存取了您的麥克風" + "「%1$s」於 %2$s前存取了您的手機" + "「%1$s」於 %2$s前存取了您的感應器" + "「%1$s」於 %2$s前存取了您的短訊" + "「%1$s」於 %2$s前存取了您的儲存空間" + "「%1$s」沒有存取您的%2$s" + "「%1$s」沒有存取您的運動資料" + "「%1$s」沒有存取您的日曆" + "「%1$s」沒有存取您的通話記錄" + "「%1$s」沒有存取您的相機" + "「%1$s」沒有存取您的聯絡人" + "「%1$s」沒有存取您的位置" + "「%1$s」沒有存取您的麥克風" + "「%1$s」沒有存取您的手機" + "「%1$s」沒有存取您的感應器" + "「%1$s」沒有存取您的短訊" + "「%1$s」沒有存取您的儲存空間" "目前無法提供此權限的上次存取資料" "查看「%1$s」的所有權限" "查看擁有此權限的所有應用程式" diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml index 8fb392260..7c8ef70a3 100644 --- a/res/values-zh-rTW/strings.xml +++ b/res/values-zh-rTW/strings.xml @@ -145,8 +145,30 @@ "拒絕" "%1$s權限" "是否允許這個應用程式存取%1$s" - "「%1$s」在 %3$s前存取了你的%2$s" - "「%1$s」並未存取你的%2$s" + "「%1$s」在 %3$s前存取了你的%2$s" + "「%1$s」在 %2$s前存取了你的體能活動記錄" + "「%1$s」在 %2$s前存取了你的日曆" + "「%1$s」在 %2$s前存取了你的通話記錄" + "「%1$s」在 %2$s前存取了你的相機" + "「%1$s」在 %2$s前存取了你的聯絡人" + "「%1$s」在 %2$s前存取了你的位置資訊" + "「%1$s」在 %2$s前存取了你的麥克風" + "「%1$s」在 %2$s前存取了你的電話" + "「%1$s」在 %2$s前存取了你的感應器" + "「%1$s」在 %2$s前存取了你的簡訊" + "「%1$s」在 %2$s前存取了你的儲存空間" + "「%1$s」並未存取你的%2$s" + "「%1$s」並未存取你的體能活動記錄" + "「%1$s」並未存取你的日曆" + "「%1$s」並未存取你的通話記錄" + "「%1$s」並未存取你的相機" + "「%1$s」並未存取你的聯絡人" + "「%1$s」並未存取你的位置資訊" + "「%1$s」並未存取你的麥克風" + "「%1$s」並未存取你的電話" + "「%1$s」並未存取你的感應器" + "「%1$s」並未存取你的簡訊" + "「%1$s」並未存取你的儲存空間" "目前無法提供這個權限的上次存取資料" "查看「%1$s」的所有權限" "查看具備此權限的所有應用程式" diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml index 0c01f7401..fc9298412 100644 --- a/res/values-zu/strings.xml +++ b/res/values-zu/strings.xml @@ -145,8 +145,30 @@ "Phika" "%1$s imvume" "%1$s ukufinyelela kwalolu hlelolo kusebenza" - "I-%1$s ifinyelele ku-%2$s yakho nge-%3$s edlule" - "I-%1$s ayifinyelelanga ku-%2$s yakho" + "I-%1$s ifinyelele ku-%2$s yakho nge-%3$s edlule" + "%1$s ufinyelele umsebenzi wakho %2$s odlule" + "%1$s ufinyelelel ikhalenda yakho %2$s odlule" + "%1$s ufinyelelele amalogi akho ekholi %2$s odlule" + "%1$s ufinyelele ikhamera yakho %2$s odlule" + "%1$s ufinyelele oxhumana nabo %2$s odlule" + "%1$s ufinyelele indawo yakho %2$s odlule" + "%1$s ufinyelele imakrofoni yakho %2$s odlule" + "%1$s ufinyelele ifoni yakho %2$s odlule" + "%1$s ufinyelelel izinzwa zakho %2$s odlule" + "%1$s ufinyelele i-SMS yakho %2$s odlule" + "%1$s ufinyelelel isitoreji sakho %2$s odlule" + "I-%1$s ayifinyelelanga ku-%2$s yakho" + "%1$s akafinyelelanga umsebenzi wakho" + "%1$s akafinyelelanga ikhalenda yakho" + "%1$s akafinyelelanga amalogi wamakholi akho" + "%1$s akafinyelelanga ikhamera yakho" + "%1$s akafinyelelanga oxhumana nabo" + "%1$s akafinyelelanga indawo yakho" + "%1$s akafinyelelanga imakrofoni yakho" + "%1$s akafinyelelanga ifoni yakho" + "%1$s akafinyelelanga izinzwa zakho" + "%1$s akafinyelelanga i-SMS yakho" + "%1$s akafinyelelanga isitoreji sakho" "Idatha yokugcina efinyelelwe okwamanje ayitholakaleli le mvume" "Bona zonke izimvume ze-%1$s" "Bona zonke izinhlelo zokusebenza ngale mvume" -- GitLab From f75c68ada3e52a369cdd7aaa68fbb760621608db Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Fri, 3 May 2019 14:17:33 -0700 Subject: [PATCH 621/701] Improve links in AppPermissionFragment. Show the links when Permissions Hub is disabled. Disable a link if it would take us back to the caller. Fixes: 131923747 Test: Open screen from four callers and see correct links with Permissions Hub enabled and disabled. Change-Id: I421ccce14e5880b308a5ad079645fd2ca0b2631b --- res/layout/app_permission.xml | 3 +-- .../permission/ui/AppPermissionActivity.java | 7 ++++++- .../ui/handheld/AppPermissionFragment.java | 20 +++++++++++++------ .../ui/handheld/AppPermissionsFragment.java | 2 +- .../ui/handheld/PermissionAppsFragment.java | 3 ++- .../handheld/PermissionControlPreference.java | 4 +++- .../ui/handheld/PermissionUsageFragment.java | 2 +- 7 files changed, 28 insertions(+), 13 deletions(-) diff --git a/res/layout/app_permission.xml b/res/layout/app_permission.xml index fb8e0e1f2..4afb1d810 100644 --- a/res/layout/app_permission.xml +++ b/res/layout/app_permission.xml @@ -92,7 +92,6 @@ - \ No newline at end of file + diff --git a/src/com/android/packageinstaller/permission/ui/AppPermissionActivity.java b/src/com/android/packageinstaller/permission/ui/AppPermissionActivity.java index 9c116e7b0..87702d3f2 100644 --- a/src/com/android/packageinstaller/permission/ui/AppPermissionActivity.java +++ b/src/com/android/packageinstaller/permission/ui/AppPermissionActivity.java @@ -38,6 +38,9 @@ import com.android.packageinstaller.permission.utils.Utils; public final class AppPermissionActivity extends FragmentActivity { private static final String LOG_TAG = AppPermissionActivity.class.getSimpleName(); + public static final String EXTRA_CALLER_NAME = + "com.android.packageinstaller.extra.CALLER_NAME"; + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -83,8 +86,10 @@ public final class AppPermissionActivity extends FragmentActivity { return; } + String caller = getIntent().getStringExtra(EXTRA_CALLER_NAME); + Fragment androidXFragment = AppPermissionFragment.newInstance(packageName, permissionName, - groupName, userHandle); + groupName, userHandle, caller); getSupportFragmentManager().beginTransaction().replace(android.R.id.content, androidXFragment).commit(); diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java index b0d53945b..46267b9ed 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java @@ -55,6 +55,7 @@ import androidx.fragment.app.Fragment; import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.model.Permission; import com.android.packageinstaller.permission.model.PermissionUsages; +import com.android.packageinstaller.permission.ui.AppPermissionActivity; import com.android.packageinstaller.permission.utils.LocationUtils; import com.android.packageinstaller.permission.utils.PackageRemovalMonitor; import com.android.packageinstaller.permission.utils.SafetyNetLogger; @@ -111,7 +112,8 @@ public class AppPermissionFragment extends SettingsWithLargeHeader { * @return A new fragment */ public static @NonNull AppPermissionFragment newInstance(@NonNull String packageName, - @NonNull String permName, @Nullable String groupName, @NonNull UserHandle userHandle) { + @NonNull String permName, @Nullable String groupName, @NonNull UserHandle userHandle, + @Nullable String caller) { AppPermissionFragment fragment = new AppPermissionFragment(); Bundle arguments = new Bundle(); arguments.putString(Intent.EXTRA_PACKAGE_NAME, packageName); @@ -121,6 +123,7 @@ public class AppPermissionFragment extends SettingsWithLargeHeader { arguments.putString(Intent.EXTRA_PERMISSION_GROUP_NAME, groupName); } arguments.putParcelable(Intent.EXTRA_USER, userHandle); + arguments.putString(AppPermissionActivity.EXTRA_CALLER_NAME, caller); fragment.setArguments(arguments); return fragment; } @@ -192,7 +195,9 @@ public class AppPermissionFragment extends SettingsWithLargeHeader { ((TextView) root.requireViewById(R.id.permission_message)).setText( context.getString(R.string.app_permission_header, mGroup.getLabel())); - if (Utils.isModernPermissionGroup(mGroup.getName())) { + if (!Utils.isPermissionsHubEnabled()) { + root.requireViewById(R.id.usage_summary).setVisibility(View.GONE); + } else if (Utils.isModernPermissionGroup(mGroup.getName())) { if (!Utils.shouldShowPermissionUsage(mGroup.getName())) { ((TextView) root.requireViewById(R.id.usage_summary)).setText( context.getString(R.string.app_permission_footer_not_available)); @@ -224,6 +229,13 @@ public class AppPermissionFragment extends SettingsWithLargeHeader { context.startActivity(intent); }); + String caller = getArguments().getString(AppPermissionActivity.EXTRA_CALLER_NAME); + if (AppPermissionsFragment.class.getName().equals(caller)) { + footer1Link.setVisibility(View.GONE); + } else if (PermissionAppsFragment.class.getName().equals(caller)) { + footer2Link.setVisibility(View.GONE); + } + mRadioGroup = root.requireViewById(R.id.radiogroup); mAlwaysButton = root.requireViewById(R.id.allow_radio_button); mForegroundOnlyButton = root.requireViewById(R.id.foreground_only_radio_button); @@ -234,10 +246,6 @@ public class AppPermissionFragment extends SettingsWithLargeHeader { mNestedScrollView = root.requireViewById(R.id.nested_scroll_view); - if (!Utils.isPermissionsHubEnabled()) { - root.requireViewById(R.id.footer_all).setVisibility(View.GONE); - } - return root; } diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java index 0faf3a009..81c22a8a4 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java @@ -224,7 +224,7 @@ public final class AppPermissionsFragment extends SettingsWithLargeHeader { boolean isPlatform = group.getDeclaringPackage().equals(Utils.OS_PKG); PermissionControlPreference preference = new PermissionControlPreference(context, - group); + group, AppPermissionsFragment.class.getName()); preference.setKey(group.getName()); Drawable icon = Utils.loadDrawable(context.getPackageManager(), group.getIconPkg(), group.getIconResId()); diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java index 1a4b5c62c..0f4ccd8fa 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java @@ -301,7 +301,8 @@ public final class PermissionAppsFragment extends SettingsWithLargeHeader implem continue; } - PermissionControlPreference pref = new PermissionControlPreference(context, group); + PermissionControlPreference pref = new PermissionControlPreference(context, group, + PermissionAppsFragment.class.getName()); pref.setKey(key); pref.setIcon(app.getIcon()); pref.setTitle(Utils.getFullAppLabel(app.getAppInfo(), context)); diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionControlPreference.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionControlPreference.java index 7bd38fa41..362358b4e 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionControlPreference.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionControlPreference.java @@ -33,6 +33,7 @@ import androidx.preference.PreferenceViewHolder; import com.android.packageinstaller.permission.model.AppPermissionGroup; import com.android.packageinstaller.permission.model.AppPermissionUsage.GroupUsage; +import com.android.packageinstaller.permission.ui.AppPermissionActivity; import com.android.permissioncontroller.R; import java.util.List; @@ -49,7 +50,7 @@ public class PermissionControlPreference extends Preference { private @Nullable List mSummaryIcons; public PermissionControlPreference(@NonNull Context context, - @NonNull AppPermissionGroup group) { + @NonNull AppPermissionGroup group, @NonNull String caller) { super(context); mContext = context; mWidgetIcon = null; @@ -62,6 +63,7 @@ public class PermissionControlPreference extends Preference { intent.putExtra(Intent.EXTRA_PACKAGE_NAME, group.getApp().packageName); intent.putExtra(Intent.EXTRA_PERMISSION_NAME, group.getPermissions().get(0).getName()); intent.putExtra(Intent.EXTRA_USER, group.getUser()); + intent.putExtra(AppPermissionActivity.EXTRA_CALLER_NAME, caller); context.startActivity(intent); return true; }); diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java index 07586cd94..4e444d726 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java @@ -655,7 +655,7 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements @NonNull AppPermissionUsage appPermissionUsage, @NonNull GroupUsage groupUsage, @NonNull String accessTimeStr) { final PermissionControlPreference pref = new PermissionControlPreference(context, - groupUsage.getGroup()); + groupUsage.getGroup(), PermissionUsageFragment.class.getName()); final AppPermissionGroup group = groupUsage.getGroup(); pref.setTitle(group.getLabel()); -- GitLab From 344b9fbea030c0bfc9642ca25d4e11f16a1d7ba8 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Fri, 3 May 2019 15:44:27 -0700 Subject: [PATCH 622/701] Have AllAppPermissionsFragment use large header. Fixes: 131924774 Test: View screen. Change-Id: I894111b8408a750f0355baf4f6ad02e2f3ae4e41 --- .../permission/ui/handheld/AllAppPermissionsFragment.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AllAppPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AllAppPermissionsFragment.java index ce75f4097..5276f7a1c 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AllAppPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AllAppPermissionsFragment.java @@ -59,7 +59,7 @@ import java.util.List; * *

Shows the list of individual runtime and non-runtime permissions the app has requested. */ -public final class AllAppPermissionsFragment extends SettingsWithHeader { +public final class AllAppPermissionsFragment extends SettingsWithLargeHeader { private static final String LOG_TAG = "AllAppPermissionsFragment"; @@ -141,7 +141,7 @@ public final class AllAppPermissionsFragment extends SettingsWithHeader { infoIntent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) .setData(Uri.fromParts("package", pkg, null)); } - setHeader(icon, label, infoIntent, userHandle); + setHeader(icon, label, infoIntent, userHandle, false); if (info.requestedPermissions != null) { for (int i = 0; i < info.requestedPermissions.length; i++) { -- GitLab From 22e3da5ac0102a15c4ad5d79125e110e2979ece0 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Fri, 3 May 2019 15:49:13 -0700 Subject: [PATCH 623/701] Allow the header icon to be clickable from the toggle screen. With this, the link will be clickable as long as we did not come from app info. Bug: 131859961 Test: Cannot click icons when coming from app info. Test: Can click icons when coming from other screens. Change-Id: Ic12f84fa640ab2b0a22b5d748ad5dd8985721b39 --- .../permission/ui/handheld/AppPermissionFragment.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java index 46267b9ed..93045c536 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java @@ -217,7 +217,6 @@ public class AppPermissionFragment extends SettingsWithLargeHeader { Intent intent = new Intent(Intent.ACTION_MANAGE_APP_PERMISSIONS); intent.putExtra(Intent.EXTRA_PACKAGE_NAME, mGroup.getApp().packageName); intent.putExtra(Intent.EXTRA_USER, user); - intent.putExtra(AppPermissionsFragment.EXTRA_HIDE_INFO_BUTTON, true); context.startActivity(intent); }); -- GitLab From 21141655e400e4edd11b4cb108863c5c3f828d1b Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Mon, 6 May 2019 08:58:44 -0700 Subject: [PATCH 624/701] Fix minor Talkback issues. Fixes: 132047086 Fixes: 132050707 Test: Select non-linkable preferences with Talkback. Test: Click on clickable icon in header with Talkback. Change-Id: I9362b10b6dfc90b8a05ec0456c0ebae3ed98ae41 --- .../permission/ui/handheld/AppPermissionsFragment.java | 2 ++ .../permission/ui/handheld/PermissionAppsFragment.java | 3 +++ .../permission/ui/handheld/SettingsWithLargeHeader.java | 1 + 3 files changed, 6 insertions(+) diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java index 81c22a8a4..26cebb51a 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java @@ -298,11 +298,13 @@ public final class AppPermissionsFragment extends SettingsWithLargeHeader { if (allowed.getPreferenceCount() == 0) { Preference empty = new Preference(context); empty.setTitle(getString(R.string.no_permissions_allowed)); + empty.setSelectable(false); allowed.addPreference(empty); } if (denied.getPreferenceCount() == 0) { Preference empty = new Preference(context); empty.setTitle(getString(R.string.no_permissions_denied)); + empty.setSelectable(false); denied.addPreference(empty); } diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java index 0f4ccd8fa..e9192ba27 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java @@ -361,6 +361,7 @@ public final class PermissionAppsFragment extends SettingsWithLargeHeader implem if (allowed.getPreferenceCount() == 0) { Preference empty = new Preference(context); empty.setTitle(getString(R.string.no_apps_allowed)); + empty.setSelectable(false); allowed.addPreference(empty); } if (allowedForeground.getPreferenceCount() == 0) { @@ -371,6 +372,7 @@ public final class PermissionAppsFragment extends SettingsWithLargeHeader implem if (denied.getPreferenceCount() == 0) { Preference empty = new Preference(context); empty.setTitle(getString(R.string.no_apps_denied)); + empty.setSelectable(false); denied.addPreference(empty); } @@ -382,6 +384,7 @@ public final class PermissionAppsFragment extends SettingsWithLargeHeader implem Preference footerText = new Preference(context); footerText.setSummary(context.getString(R.string.app_permission_footer_not_available)); footerText.setIcon(R.drawable.ic_info_outline); + footerText.setSelectable(false); footer.addPreference(footerText); } diff --git a/src/com/android/packageinstaller/permission/ui/handheld/SettingsWithLargeHeader.java b/src/com/android/packageinstaller/permission/ui/handheld/SettingsWithLargeHeader.java index 9cd39bc1b..a613b2af5 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/SettingsWithLargeHeader.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/SettingsWithLargeHeader.java @@ -102,6 +102,7 @@ public abstract class SettingsWithLargeHeader extends PermissionsFrameFragment if (mInfoIntent != null) { appIcon.setOnClickListener(v -> getActivity().startActivityAsUser(mInfoIntent, mUserHandle)); + appIcon.setContentDescription(mLabel); } TextView appName = header.requireViewById(R.id.entity_header_title); -- GitLab From 5312a66d761666a67f5e75012638e398ccffeeb1 Mon Sep 17 00:00:00 2001 From: Heemin Seog Date: Thu, 18 Apr 2019 16:28:26 -0700 Subject: [PATCH 625/701] Theme secondary default app picker screen for car settings One major difference is that car settings doesn't use radio buttons. Instead it uses "Selected" string in the summary field to denote the default app. For (system apps)s, the text will appear as "Selected - (System app)" Bug: 130348508 Test: manual Change-Id: Iac2e45add29cd923b77c685064aa0d5d65e39965 --- res/values/strings.xml | 6 + res/values/themes.xml | 7 +- .../role/ui/DefaultAppActivity.java | 17 ++- .../role/ui/auto/AutoDefaultAppFragment.java | 104 ++++++++++++++++++ .../ui/auto/AutoDefaultAppPreference.java | 72 ++++++++++++ .../role/ui/auto/AutoSettingsPreference.java | 1 - 6 files changed, 198 insertions(+), 9 deletions(-) create mode 100644 src/com/android/packageinstaller/role/ui/auto/AutoDefaultAppFragment.java create mode 100644 src/com/android/packageinstaller/role/ui/auto/AutoDefaultAppPreference.java diff --git a/res/values/strings.xml b/res/values/strings.xml index d9512f3cf..0b3d9b8e9 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -765,6 +765,12 @@ No apps + + Selected + + + Selected - %1$s + special app access diff --git a/res/values/themes.xml b/res/values/themes.xml index 848cd78a3..1f064bda4 100644 --- a/res/values/themes.xml +++ b/res/values/themes.xml @@ -23,11 +23,6 @@ @style/TextAppearance.CategoryTitle - - - diff --git a/src/com/android/packageinstaller/role/ui/DefaultAppActivity.java b/src/com/android/packageinstaller/role/ui/DefaultAppActivity.java index 502a87a7b..8c905f58b 100644 --- a/src/com/android/packageinstaller/role/ui/DefaultAppActivity.java +++ b/src/com/android/packageinstaller/role/ui/DefaultAppActivity.java @@ -26,11 +26,15 @@ import android.view.WindowManager; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; +import com.android.packageinstaller.DeviceUtils; import com.android.packageinstaller.role.model.Role; import com.android.packageinstaller.role.model.Roles; +import com.android.packageinstaller.role.ui.auto.AutoDefaultAppFragment; import com.android.packageinstaller.role.ui.handheld.HandheldDefaultAppFragment; +import com.android.permissioncontroller.R; /** * Activity for a default app. @@ -58,6 +62,11 @@ public class DefaultAppActivity extends FragmentActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { + if (DeviceUtils.isAuto(this)) { + // Automotive relies on a different theme. Apply before calling super so that + // fragments are restored properly on configuration changes. + setTheme(R.style.CarSettings); + } super.onCreate(savedInstanceState); getWindow().addSystemFlags( @@ -89,8 +98,12 @@ public class DefaultAppActivity extends FragmentActivity { } if (savedInstanceState == null) { - HandheldDefaultAppFragment fragment = HandheldDefaultAppFragment.newInstance(roleName, - user); + Fragment fragment; + if (DeviceUtils.isAuto(this)) { + fragment = AutoDefaultAppFragment.newInstance(roleName, user); + } else { + fragment = HandheldDefaultAppFragment.newInstance(roleName, user); + } getSupportFragmentManager().beginTransaction() .add(android.R.id.content, fragment) .commit(); diff --git a/src/com/android/packageinstaller/role/ui/auto/AutoDefaultAppFragment.java b/src/com/android/packageinstaller/role/ui/auto/AutoDefaultAppFragment.java new file mode 100644 index 000000000..daa3456b0 --- /dev/null +++ b/src/com/android/packageinstaller/role/ui/auto/AutoDefaultAppFragment.java @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2019 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.packageinstaller.role.ui.auto; + +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.os.UserHandle; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.preference.Preference; +import androidx.preference.TwoStatePreference; + +import com.android.packageinstaller.role.model.Role; +import com.android.packageinstaller.role.ui.DefaultAppChildFragment; +import com.android.permissioncontroller.R; + +/** Screen to pick a default app for a particular {@link Role}. */ +public class AutoDefaultAppFragment extends DefaultAppFrameFragment implements + DefaultAppChildFragment.Parent { + + private String mRoleName; + + private UserHandle mUser; + + /** + * Create a new instance of this fragment. + * + * @param roleName the name of the role for the default app + * @param user the user for the default app + * @return a new instance of this fragment + */ + @NonNull + public static AutoDefaultAppFragment newInstance(@NonNull String roleName, + @NonNull UserHandle user) { + AutoDefaultAppFragment fragment = new AutoDefaultAppFragment(); + Bundle arguments = new Bundle(); + arguments.putString(Intent.EXTRA_ROLE_NAME, roleName); + arguments.putParcelable(Intent.EXTRA_USER, user); + fragment.setArguments(arguments); + return fragment; + } + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + Bundle arguments = getArguments(); + mRoleName = arguments.getString(Intent.EXTRA_ROLE_NAME); + mUser = arguments.getParcelable(Intent.EXTRA_USER); + } + + @Override + public void onActivityCreated(@Nullable Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + if (savedInstanceState == null) { + DefaultAppChildFragment fragment = DefaultAppChildFragment.newInstance(mRoleName, + mUser); + getChildFragmentManager().beginTransaction() + .add(fragment, null) + .commit(); + } + } + + @Override + public void setTitle(@NonNull CharSequence title) { + setHeaderLabel(title); + } + + @NonNull + @Override + public TwoStatePreference createApplicationPreference(@NonNull Context context) { + return new AutoDefaultAppPreference(context); + } + + @NonNull + @Override + public Preference createFooterPreference(@NonNull Context context) { + Preference preference = new Preference(context); + preference.setIcon(R.drawable.ic_info_outline); + preference.setSelectable(false); + return preference; + } + + @Override + public void onPreferenceScreenChanged() { + } +} diff --git a/src/com/android/packageinstaller/role/ui/auto/AutoDefaultAppPreference.java b/src/com/android/packageinstaller/role/ui/auto/AutoDefaultAppPreference.java new file mode 100644 index 000000000..0eba6b4ef --- /dev/null +++ b/src/com/android/packageinstaller/role/ui/auto/AutoDefaultAppPreference.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2019 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.packageinstaller.role.ui.auto; + +import android.content.Context; +import android.text.TextUtils; +import android.util.AttributeSet; +import android.view.View; +import android.widget.TextView; + +import androidx.preference.PreferenceViewHolder; +import androidx.preference.TwoStatePreference; + +import com.android.permissioncontroller.R; + +/** Preference used to represent apps that can be picked as a default app. */ +public class AutoDefaultAppPreference extends TwoStatePreference { + + public AutoDefaultAppPreference(Context context, AttributeSet attrs, + int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + } + + public AutoDefaultAppPreference(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + public AutoDefaultAppPreference(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public AutoDefaultAppPreference(Context context) { + super(context); + } + + @Override + public void onBindViewHolder(PreferenceViewHolder holder) { + super.onBindViewHolder(holder); + + TextView summaryView = (TextView) holder.findViewById(android.R.id.summary); + if (summaryView == null) { + return; + } + + if (isChecked()) { + CharSequence current = getSummary(); + CharSequence selected = getContext().getString(R.string.car_default_app_selected); + if (!TextUtils.isEmpty(current)) { + selected = getContext().getString(R.string.car_default_app_selected_with_info, + current); + } + summaryView.setText(selected); + summaryView.setVisibility(View.VISIBLE); + } else { + summaryView.setVisibility(View.GONE); + } + } +} diff --git a/src/com/android/packageinstaller/role/ui/auto/AutoSettingsPreference.java b/src/com/android/packageinstaller/role/ui/auto/AutoSettingsPreference.java index 56e16a63a..dec661863 100644 --- a/src/com/android/packageinstaller/role/ui/auto/AutoSettingsPreference.java +++ b/src/com/android/packageinstaller/role/ui/auto/AutoSettingsPreference.java @@ -50,6 +50,5 @@ public class AutoSettingsPreference extends TwoTargetPreference { @Override public void setOnSecondTargetClickListener(@Nullable OnSecondTargetClickListener listener) { - return; } } -- GitLab From 6210832dbd828b6c537a66e9132d45d9312bc6ca Mon Sep 17 00:00:00 2001 From: Evan Severson Date: Mon, 6 May 2019 11:37:59 -0700 Subject: [PATCH 626/701] Foreground permission request UI similar to tristate Foreground permission to look same as tristate but without the "Allow all the time" button. Also hide the "Deny" button for tristate when deny with prejudice is also available. Fixes: 132030782 Bug: 131176061 Test: Build and look at various permission grant dialogs Change-Id: I4f2d01542b677535077e8b045e5ff2bb4e14b68a --- .../permission/ui/GrantPermissionsActivity.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java b/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java index 73b393233..0fda6e7de 100644 --- a/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java +++ b/src/com/android/packageinstaller/permission/ui/GrantPermissionsActivity.java @@ -650,12 +650,17 @@ public class GrantPermissionsActivity extends Activity if (needForegroundPermission) { messageId = groupState.mGroup.getRequest(); - if (needBackgroundPermission) { + if (groupState.mGroup.hasPermissionWithBackgroundMode()) { buttonLabels[LABEL_ALLOW_BUTTON] = null; - buttonLabels[LABEL_ALLOW_ALWAYS_BUTTON] = - getString(R.string.grant_dialog_button_allow_always); buttonLabels[LABEL_ALLOW_FOREGROUND_BUTTON] = getString(R.string.grant_dialog_button_allow_foreground); + if (needBackgroundPermission) { + buttonLabels[LABEL_ALLOW_ALWAYS_BUTTON] = + getString(R.string.grant_dialog_button_allow_always); + if (isForegroundPermissionUserSet || isBackgroundPermissionUserSet) { + buttonLabels[LABEL_DENY_BUTTON] = null; + } + } } else { detailMessageId = groupState.mGroup.getRequestDetail(); } -- GitLab From f1ebe3b6c00bf2d1ad43827bc53ad8ceab46bbcf Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Thu, 2 May 2019 16:00:16 +0800 Subject: [PATCH 627/701] Add stats log for requesting a role. Bug: 131449546 Test: presubmit Change-Id: Ide7659b7ffe3f26d6b4545310440d2452f829e79 --- .../role/ui/RequestRoleActivity.java | 41 ++++++ .../role/ui/RequestRoleFragment.java | 124 +++++++++++++++++- 2 files changed, 163 insertions(+), 2 deletions(-) diff --git a/src/com/android/packageinstaller/role/ui/RequestRoleActivity.java b/src/com/android/packageinstaller/role/ui/RequestRoleActivity.java index 913cceae5..8fa75c89d 100644 --- a/src/com/android/packageinstaller/role/ui/RequestRoleActivity.java +++ b/src/com/android/packageinstaller/role/ui/RequestRoleActivity.java @@ -17,6 +17,7 @@ package com.android.packageinstaller.role.ui; import android.app.role.RoleManager; +import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.os.Build; @@ -26,9 +27,11 @@ import android.text.TextUtils; import android.util.Log; import android.view.WindowManager; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.FragmentActivity; +import com.android.packageinstaller.PermissionControllerStatsLog; import com.android.packageinstaller.role.model.Role; import com.android.packageinstaller.role.model.Roles; import com.android.packageinstaller.role.model.UserDeniedManager; @@ -61,11 +64,15 @@ public class RequestRoleActivity extends FragmentActivity { if (TextUtils.isEmpty(mRoleName)) { Log.w(LOG_TAG, "Role name cannot be null or empty: " + mRoleName); + reportRequestResult( + PermissionControllerStatsLog.ROLE_REQUEST_RESULT_REPORTED__RESULT__IGNORED); finish(); return; } if (TextUtils.isEmpty(mPackageName)) { Log.w(LOG_TAG, "Package name cannot be null or empty: " + mPackageName); + reportRequestResult( + PermissionControllerStatsLog.ROLE_REQUEST_RESULT_REPORTED__RESULT__IGNORED); finish(); return; } @@ -74,36 +81,48 @@ public class RequestRoleActivity extends FragmentActivity { Role role = Roles.get(this).get(mRoleName); if (role == null) { Log.w(LOG_TAG, "Unknown role: " + mRoleName); + reportRequestResult( + PermissionControllerStatsLog.ROLE_REQUEST_RESULT_REPORTED__RESULT__IGNORED); finish(); return; } if (!role.isAvailable(this)) { Log.e(LOG_TAG, "Role is unavailable: " + mRoleName); + reportRequestResult( + PermissionControllerStatsLog.ROLE_REQUEST_RESULT_REPORTED__RESULT__IGNORED); finish(); return; } if (!role.isVisible(this)) { Log.e(LOG_TAG, "Role is invisible: " + mRoleName); + reportRequestResult( + PermissionControllerStatsLog.ROLE_REQUEST_RESULT_REPORTED__RESULT__IGNORED); finish(); return; } if (!role.isRequestable()) { Log.e(LOG_TAG, "Role is not requestable: " + mRoleName); + reportRequestResult( + PermissionControllerStatsLog.ROLE_REQUEST_RESULT_REPORTED__RESULT__IGNORED); finish(); return; } if (!role.isExclusive()) { Log.e(LOG_TAG, "Role is not exclusive: " + mRoleName); + reportRequestResult( + PermissionControllerStatsLog.ROLE_REQUEST_RESULT_REPORTED__RESULT__IGNORED); finish(); return; } if (PackageUtils.getApplicationInfo(mPackageName, this) == null) { Log.w(LOG_TAG, "Unknown application: " + mPackageName); + reportRequestResult( + PermissionControllerStatsLog.ROLE_REQUEST_RESULT_REPORTED__RESULT__IGNORED); finish(); return; } @@ -113,6 +132,8 @@ public class RequestRoleActivity extends FragmentActivity { if (currentPackageNames.contains(mPackageName)) { Log.i(LOG_TAG, "Application is already a role holder, role: " + mRoleName + ", package: " + mPackageName); + reportRequestResult(PermissionControllerStatsLog + .ROLE_REQUEST_RESULT_REPORTED__RESULT__IGNORED_ALREADY_GRANTED); setResult(RESULT_OK); finish(); return; @@ -121,6 +142,8 @@ public class RequestRoleActivity extends FragmentActivity { if (!role.isPackageQualified(mPackageName, this)) { Log.w(LOG_TAG, "Application doesn't qualify for role, role: " + mRoleName + ", package: " + mPackageName); + reportRequestResult(PermissionControllerStatsLog + .ROLE_REQUEST_RESULT_REPORTED__RESULT__IGNORED_NOT_QUALIFIED); finish(); return; } @@ -128,6 +151,8 @@ public class RequestRoleActivity extends FragmentActivity { if (UserDeniedManager.getInstance(this).isDeniedAlways(mRoleName, mPackageName)) { Log.w(LOG_TAG, "Application is denied always for role, role: " + mRoleName + ", package: " + mPackageName); + reportRequestResult(PermissionControllerStatsLog + .ROLE_REQUEST_RESULT_REPORTED__RESULT__IGNORED_USER_ALWAYS_DENIED); finish(); return; } @@ -184,4 +209,20 @@ public class RequestRoleActivity extends FragmentActivity { } } } + + private void reportRequestResult(int result) { + RequestRoleFragment.reportRequestResult(getApplicationUid(mPackageName, this), mPackageName, + mRoleName, -1, -1, null, -1, null, result); + } + + private static int getApplicationUid(@Nullable String packageName, @NonNull Context context) { + if (packageName == null) { + return -1; + } + ApplicationInfo applicationInfo = PackageUtils.getApplicationInfo(packageName, context); + if (applicationInfo == null) { + return -1; + } + return applicationInfo.uid; + } } diff --git a/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java b/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java index 22cbfd861..a1af450ab 100644 --- a/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java +++ b/src/com/android/packageinstaller/role/ui/RequestRoleFragment.java @@ -48,6 +48,7 @@ import androidx.appcompat.content.res.AppCompatResources; import androidx.fragment.app.DialogFragment; import androidx.lifecycle.ViewModelProviders; +import com.android.packageinstaller.PermissionControllerStatsLog; import com.android.packageinstaller.permission.utils.PackageRemovalMonitor; import com.android.packageinstaller.permission.utils.Utils; import com.android.packageinstaller.role.model.Role; @@ -123,6 +124,8 @@ public class RequestRoleFragment extends DialogFragment { if (currentPackageNames.contains(mPackageName)) { Log.i(LOG_TAG, "Application is already a role holder, role: " + mRoleName + ", package: " + mPackageName); + reportRequestResult(PermissionControllerStatsLog + .ROLE_REQUEST_RESULT_REPORTED__RESULT__IGNORED_ALREADY_GRANTED, null); clearDeniedSetResultOkAndFinish(); return super.onCreateDialog(savedInstanceState); } @@ -130,6 +133,9 @@ public class RequestRoleFragment extends DialogFragment { ApplicationInfo applicationInfo = PackageUtils.getApplicationInfo(mPackageName, context); if (applicationInfo == null) { Log.w(LOG_TAG, "Unknown application: " + mPackageName); + reportRequestResult( + PermissionControllerStatsLog.ROLE_REQUEST_RESULT_REPORTED__RESULT__IGNORED, + null); finish(); return super.onCreateDialog(savedInstanceState); } @@ -190,6 +196,9 @@ public class RequestRoleFragment extends DialogFragment { Context context = requireContext(); if (PackageUtils.getApplicationInfo(mPackageName, context) == null) { Log.w(LOG_TAG, "Unknown application: " + mPackageName); + reportRequestResult( + PermissionControllerStatsLog.ROLE_REQUEST_RESULT_REPORTED__RESULT__IGNORED, + null); finish(); return; } @@ -199,6 +208,9 @@ public class RequestRoleFragment extends DialogFragment { protected void onPackageRemoved() { Log.w(LOG_TAG, "Application is uninstalled, role: " + mRoleName + ", package: " + mPackageName); + reportRequestResult( + PermissionControllerStatsLog.ROLE_REQUEST_RESULT_REPORTED__RESULT__IGNORED, + null); finish(); } }; @@ -239,6 +251,9 @@ public class RequestRoleFragment extends DialogFragment { super.onCancel(dialog); Log.i(LOG_TAG, "Dialog cancelled, role: " + mRoleName + ", package: " + mPackageName); + reportRequestResult( + PermissionControllerStatsLog.ROLE_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED, + null); setDeniedOnceAndFinish(); } @@ -251,6 +266,8 @@ public class RequestRoleFragment extends DialogFragment { if (mDontAskAgainCheck != null && mDontAskAgainCheck.isChecked()) { Log.i(LOG_TAG, "Request denied with don't ask again, role: " + mRoleName + ", package: " + mPackageName); + reportRequestResult(PermissionControllerStatsLog + .ROLE_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED_WITH_ALWAYS, null); setDeniedAlwaysAndFinish(); } else { setRoleHolder(); @@ -262,12 +279,23 @@ public class RequestRoleFragment extends DialogFragment { Context context = requireContext(); UserHandle user = Process.myUserHandle(); if (packageName == null) { + reportRequestResult(PermissionControllerStatsLog + .ROLE_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED_GRANTED_ANOTHER, + null); mRole.onNoneHolderSelectedAsUser(user, context); mViewModel.getManageRoleHolderStateLiveData().clearRoleHoldersAsUser(mRoleName, 0, user, context); } else { - int flags = Objects.equals(packageName, mPackageName) - ? RoleManager.MANAGE_HOLDERS_FLAG_DONT_KILL_APP : 0; + boolean isRequestingApplication = Objects.equals(packageName, mPackageName); + if (isRequestingApplication) { + reportRequestResult(PermissionControllerStatsLog + .ROLE_REQUEST_RESULT_REPORTED__RESULT__USER_GRANTED, null); + } else { + reportRequestResult(PermissionControllerStatsLog + .ROLE_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED_GRANTED_ANOTHER, + packageName); + } + int flags = isRequestingApplication ? RoleManager.MANAGE_HOLDERS_FLAG_DONT_KILL_APP : 0; mViewModel.getManageRoleHolderStateLiveData().setRoleHolderAsUser(mRoleName, packageName, true, flags, user, context); } @@ -299,6 +327,7 @@ public class RequestRoleFragment extends DialogFragment { break; } case ManageRoleHolderStateLiveData.STATE_FAILURE: + // TODO: Notify user? finish(); break; } @@ -336,6 +365,97 @@ public class RequestRoleFragment extends DialogFragment { requireActivity().finish(); } + private void reportRequestResult(int result, @Nullable String grantedAnotherPackageName) { + String holderPackageName = getHolderPackageName(); + reportRequestResult(getApplicationUid(mPackageName), mPackageName, mRoleName, + getQualifyingApplicationCount(), getQualifyingApplicationUid(holderPackageName), + holderPackageName, getQualifyingApplicationUid(grantedAnotherPackageName), + grantedAnotherPackageName, result); + } + + private int getApplicationUid(@NonNull String packageName) { + int uid = getQualifyingApplicationUid(packageName); + if (uid != -1) { + return uid; + } + ApplicationInfo applicationInfo = PackageUtils.getApplicationInfo(packageName, + requireActivity()); + if (applicationInfo == null) { + return -1; + } + return applicationInfo.uid; + } + + private int getQualifyingApplicationUid(@Nullable String packageName) { + if (packageName == null || mAdapter == null) { + return -1; + } + int count = mAdapter.getCount(); + for (int i = 0; i < count; i++) { + Pair qualifyingApplication = mAdapter.getItem(i); + if (qualifyingApplication == null) { + // Skip the "None" item. + continue; + } + ApplicationInfo qualifyingApplicationInfo = qualifyingApplication.first; + if (Objects.equals(qualifyingApplicationInfo.packageName, packageName)) { + return qualifyingApplicationInfo.uid; + } + } + return -1; + } + + private int getQualifyingApplicationCount() { + if (mAdapter == null) { + return -1; + } + int count = mAdapter.getCount(); + if (count > 0 && mAdapter.getItem(0) == null) { + // Exclude the "None" item. + --count; + } + return count; + } + + @Nullable + private String getHolderPackageName() { + if (mAdapter == null) { + return null; + } + int count = mAdapter.getCount(); + for (int i = 0; i < count; i++) { + Pair qualifyingApplication = mAdapter.getItem(i); + if (qualifyingApplication == null) { + // Skip the "None" item. + continue; + } + boolean isHolderApplication = qualifyingApplication.second; + if (isHolderApplication) { + return qualifyingApplication.first.packageName; + } + } + return null; + } + + static void reportRequestResult(int requestingUid, String requestingPackageName, + String roleName, int qualifyingCount, int currentUid, String currentPackageName, + int grantedAnotherUid, String grantedAnotherPackageName, int result) { + Log.v(LOG_TAG, "Role request result" + + " requestingUid=" + requestingUid + + " requestingPackageName=" + requestingPackageName + + " roleName=" + roleName + + " qualifyingCount=" + qualifyingCount + + " currentUid=" + currentUid + + " currentPackageName=" + currentPackageName + + " grantedAnotherUid=" + grantedAnotherUid + + " grantedAnotherPackageName=" + grantedAnotherPackageName + + " result=" + result); + PermissionControllerStatsLog.write( + PermissionControllerStatsLog.ROLE_REQUEST_RESULT_REPORTED, requestingUid, + requestingPackageName, roleName, qualifyingCount, currentUid, currentPackageName, + grantedAnotherUid, grantedAnotherPackageName, result); + } + private static class Adapter extends BaseAdapter { private static final String STATE_USER_CHECKED = Adapter.class.getName() -- GitLab From 489c81882c6224f4c161e6401735db9d395160df Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Tue, 30 Apr 2019 17:01:56 +0800 Subject: [PATCH 628/701] Replace SmsDefaultDialog with RequestRoleActivity. For apps targeting pre-Q, we allow specifying the package name of the application itself, or another package name if the calling app is the current default SMS app. Omitting the package name will launch the settings activity instead. For apps targeting Q or later, we'll cancel the activity launch in ActivityStackSupervisor. Bug: 124452117 Bug: 131204827 Test: Open an SMS app and observe the dialog Change-Id: I8d669164815b9c96e881b790038a47fd65976560 --- AndroidManifest.xml | 3 +- .../role/ui/RequestRoleActivity.java | 66 +++++++++++-------- 2 files changed, 40 insertions(+), 29 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index d8bfe816f..09575aa9a 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -179,8 +179,7 @@ - - + diff --git a/src/com/android/packageinstaller/role/ui/RequestRoleActivity.java b/src/com/android/packageinstaller/role/ui/RequestRoleActivity.java index 8fa75c89d..a58b256b7 100644 --- a/src/com/android/packageinstaller/role/ui/RequestRoleActivity.java +++ b/src/com/android/packageinstaller/role/ui/RequestRoleActivity.java @@ -20,8 +20,8 @@ import android.app.role.RoleManager; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; -import android.os.Build; import android.os.Bundle; +import android.os.Process; import android.provider.Telephony; import android.text.TextUtils; import android.util.Log; @@ -32,6 +32,7 @@ import androidx.annotation.Nullable; import androidx.fragment.app.FragmentActivity; import com.android.packageinstaller.PermissionControllerStatsLog; +import com.android.packageinstaller.permission.utils.CollectionUtils; import com.android.packageinstaller.role.model.Role; import com.android.packageinstaller.role.model.Roles; import com.android.packageinstaller.role.model.UserDeniedManager; @@ -60,7 +61,12 @@ public class RequestRoleActivity extends FragmentActivity { mRoleName = getIntent().getStringExtra(Intent.EXTRA_ROLE_NAME); mPackageName = getCallingPackage(); - ensureSmsDefaultDialogCompatibility(); + if (!handleSmsDefaultDialogCompatibility()) { + reportRequestResult( + PermissionControllerStatsLog.ROLE_REQUEST_RESULT_REPORTED__RESULT__IGNORED); + finish(); + return; + } if (TextUtils.isEmpty(mRoleName)) { Log.w(LOG_TAG, "Role name cannot be null or empty: " + mRoleName); @@ -167,47 +173,53 @@ public class RequestRoleActivity extends FragmentActivity { } /** - * @see com.android.settings.SmsDefaultDialog + * Handle compatibility with the old {@link com.android.settings.SmsDefaultDialog}. + * + * @return whether we should continue requesting the role. The activity should be finished if + * {@code false} is returned. */ - private void ensureSmsDefaultDialogCompatibility() { + private boolean handleSmsDefaultDialogCompatibility() { Intent intent = getIntent(); if (!Objects.equals(intent.getAction(), Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT)) { - return; - } - if (intent.hasExtra(Intent.EXTRA_ROLE_NAME)) { - // Don't allow calling legacy interface with a role name. - return; + return true; } Log.w(LOG_TAG, "Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT is deprecated; please use" + " RoleManager.createRequestRoleIntent() and Activity.startActivityForResult()" + " instead"); - if (intent.hasExtra(Intent.EXTRA_PACKAGE_NAME)) { - Log.w(LOG_TAG, "Intent.EXTRA_PACKAGE_NAME is deprecated, and will be ignored in most" - + " cases. For SMS backup, please use the new backup role instead."); - } - mRoleName = null; + mRoleName = RoleManager.ROLE_SMS; mPackageName = null; - String packageName = getCallingPackage(); - if (packageName == null) { - return; - } - ApplicationInfo applicationInfo = PackageUtils.getApplicationInfo(packageName, this); - if (applicationInfo == null || applicationInfo.targetSdkVersion >= Build.VERSION_CODES.Q) { - return; + String callingPackageName = getCallingPackage(); + String extraPackageName = intent.getStringExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME); + if (extraPackageName == null) { + // Launch the settings activity to show the list. + // TODO: Return RESULT_OK if any changes were made? + Intent defaultAppActivityIntent = DefaultAppActivity.createIntent( + RoleManager.ROLE_SMS, Process.myUserHandle(), this) + .addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT); + startActivity(defaultAppActivityIntent); + return false; } - mRoleName = RoleManager.ROLE_SMS; - mPackageName = packageName; + if (Objects.equals(extraPackageName, callingPackageName)) { + // Requesting for itself is okay. + mPackageName = extraPackageName; + return true; + } RoleManager roleManager = getSystemService(RoleManager.class); - if (roleManager.getRoleHolders(RoleManager.ROLE_SMS).contains(mPackageName)) { - if (intent.hasExtra(Intent.EXTRA_PACKAGE_NAME)) { - mPackageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME); - } + String holderPackageName = CollectionUtils.firstOrNull(roleManager.getRoleHolders( + RoleManager.ROLE_SMS)); + if (Objects.equals(callingPackageName, holderPackageName)) { + // Giving away its own role is okay. + mPackageName = extraPackageName; + return true; } + + // If we reach here it's not okay. + return false; } private void reportRequestResult(int result) { -- GitLab From 00b3239fbfd93ee8f41625d819a9d02798092c1c Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Tue, 30 Apr 2019 19:03:41 +0800 Subject: [PATCH 629/701] Replace ChangeDefaultDialerDialog with RequestRoleActivity. For apps targeting pre-Q, we allow specifying the package name of the application itself, or another package name if the calling app is the current default dialer app. For apps targeting Q or later, we'll cancel the activity launch in ActivityStackSupervisor. Bug: 124452117 Bug: 131204827 Test: presubmit Change-Id: I4ec52108321903b3875007246a95b434172849c1 --- AndroidManifest.xml | 4 ++ .../role/ui/RequestRoleActivity.java | 50 +++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 09575aa9a..d5686d9e7 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -183,6 +183,10 @@ + + + + diff --git a/src/com/android/packageinstaller/role/ui/RequestRoleActivity.java b/src/com/android/packageinstaller/role/ui/RequestRoleActivity.java index a58b256b7..44d374003 100644 --- a/src/com/android/packageinstaller/role/ui/RequestRoleActivity.java +++ b/src/com/android/packageinstaller/role/ui/RequestRoleActivity.java @@ -23,6 +23,7 @@ import android.content.pm.ApplicationInfo; import android.os.Bundle; import android.os.Process; import android.provider.Telephony; +import android.telecom.TelecomManager; import android.text.TextUtils; import android.util.Log; import android.view.WindowManager; @@ -61,6 +62,13 @@ public class RequestRoleActivity extends FragmentActivity { mRoleName = getIntent().getStringExtra(Intent.EXTRA_ROLE_NAME); mPackageName = getCallingPackage(); + if (!handleChangeDefaultDialerDialogCompatibility()) { + reportRequestResult( + PermissionControllerStatsLog.ROLE_REQUEST_RESULT_REPORTED__RESULT__IGNORED); + finish(); + return; + } + if (!handleSmsDefaultDialogCompatibility()) { reportRequestResult( PermissionControllerStatsLog.ROLE_REQUEST_RESULT_REPORTED__RESULT__IGNORED); @@ -172,6 +180,48 @@ public class RequestRoleActivity extends FragmentActivity { } } + /** + * Handle compatibility with the old + * {@link com.android.server.telecom.components.ChangeDefaultDialerDialog}. + * + * @return whether we should continue requesting the role. The activity should be finished if + * {@code false} is returned. + */ + private boolean handleChangeDefaultDialerDialogCompatibility() { + Intent intent = getIntent(); + if (!Objects.equals(intent.getAction(), TelecomManager.ACTION_CHANGE_DEFAULT_DIALER)) { + return true; + } + + Log.w(LOG_TAG, "TelecomManager.ACTION_CHANGE_DEFAULT_DIALER is deprecated; please use" + + " RoleManager.createRequestRoleIntent() and Activity.startActivityForResult()" + + " instead"); + + mRoleName = RoleManager.ROLE_DIALER; + mPackageName = null; + + String callingPackageName = getCallingPackage(); + String extraPackageName = intent.getStringExtra( + TelecomManager.EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME); + if (Objects.equals(extraPackageName, callingPackageName)) { + // Requesting for itself is okay. + mPackageName = extraPackageName; + return true; + } + + RoleManager roleManager = getSystemService(RoleManager.class); + String holderPackageName = CollectionUtils.firstOrNull(roleManager.getRoleHolders( + RoleManager.ROLE_DIALER)); + if (Objects.equals(callingPackageName, holderPackageName)) { + // Giving away its own role is okay. + mPackageName = extraPackageName; + return true; + } + + // If we reach here it's not okay. + return false; + } + /** * Handle compatibility with the old {@link com.android.settings.SmsDefaultDialog}. * -- GitLab From 708e36a6114fadf05156f5b81821f84b8115c621 Mon Sep 17 00:00:00 2001 From: Svet Ganov Date: Tue, 7 May 2019 08:26:21 -0700 Subject: [PATCH 630/701] Restricted permission whitelisted by default - PermissionController To ensure existing installers would work without a change the default state of installing a package is now that all restricted permissions are whitelisted. If the installer specifies another whitelist at install time, it determines the install state. In addition to this we now enable the restricted permission checks as a prebuilt installer is no longer required. Test: atest CtsPermission2TestCases Test: atest CtsPermissionTestCases Test: atest CtsAppSecurityTestCases:android.appsecurity.cts.PermissionsHostTest bug:132160728 Change-Id: I5634a27c21062b5f1a85de101fa2e1f0d29a1865 --- src/com/android/packageinstaller/Constants.java | 3 --- .../permission/model/AppPermissionGroup.java | 6 ++---- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/com/android/packageinstaller/Constants.java b/src/com/android/packageinstaller/Constants.java index ae23b3074..c3d7f86aa 100644 --- a/src/com/android/packageinstaller/Constants.java +++ b/src/com/android/packageinstaller/Constants.java @@ -21,9 +21,6 @@ package com.android.packageinstaller; */ public class Constants { - // STOPSHIP: Remove this once we get a Play prebuilt. - public static boolean RESTRICTED_PERMISSIONS_ENABLED = false; - /** * ID for the periodic job in * {@link com.android.packageinstaller.permission.service.LocationAccessCheck}. diff --git a/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java b/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java index 83bc45701..fab23d016 100644 --- a/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java +++ b/src/com/android/packageinstaller/permission/model/AppPermissionGroup.java @@ -44,7 +44,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.StringRes; -import com.android.packageinstaller.Constants; import com.android.packageinstaller.permission.service.LocationAccessCheck; import com.android.packageinstaller.permission.utils.ArrayUtils; import com.android.packageinstaller.permission.utils.LocationUtils; @@ -342,9 +341,8 @@ public final class AppPermissionGroup implements Comparable group.getBackgroundPermissions().addPermission(permission); } else { - if (!Constants.RESTRICTED_PERMISSIONS_ENABLED - || (!permission.isHardRestricted() - || whitelistedRestrictedPermissions.contains(permission.getName()))) { + if (!permission.isHardRestricted() + || whitelistedRestrictedPermissions.contains(permission.getName())) { group.addPermission(permission); } } -- GitLab From 3e82bd5bd3d4eaafc131c7c596127ddab385ba7f Mon Sep 17 00:00:00 2001 From: Heemin Seog Date: Tue, 7 May 2019 17:03:42 -0700 Subject: [PATCH 631/701] Add ability to hide certain roles and overlay car resources Bug: 130348508 Test: manual Change-Id: Iec392e459c7e9d863050a9e9d12b2720c034c2dd --- res/values/config.xml | 22 ++++++++++++++++ res/values/overlayable.xml | 25 +++++++++++++++++++ .../role/model/BrowserRoleBehavior.java | 7 ++++++ .../role/model/DialerRoleBehavior.java | 6 +++++ .../role/model/SmsRoleBehavior.java | 7 ++++++ 5 files changed, 67 insertions(+) create mode 100644 res/values/config.xml diff --git a/res/values/config.xml b/res/values/config.xml new file mode 100644 index 000000000..9c26d3eae --- /dev/null +++ b/res/values/config.xml @@ -0,0 +1,22 @@ + + + + + true + true + true + diff --git a/res/values/overlayable.xml b/res/values/overlayable.xml index b55187dae..7f8370c09 100644 --- a/res/values/overlayable.xml +++ b/res/values/overlayable.xml @@ -227,6 +227,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/com/android/packageinstaller/role/model/BrowserRoleBehavior.java b/src/com/android/packageinstaller/role/model/BrowserRoleBehavior.java index 3f7bd2926..56c7b7af5 100644 --- a/src/com/android/packageinstaller/role/model/BrowserRoleBehavior.java +++ b/src/com/android/packageinstaller/role/model/BrowserRoleBehavior.java @@ -29,6 +29,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.packageinstaller.role.utils.UserUtils; +import com.android.permissioncontroller.R; import java.util.ArrayList; import java.util.List; @@ -113,4 +114,10 @@ public class BrowserRoleBehavior implements RoleBehavior { } return new ArrayList<>(packageNames); } + + @Override + public boolean isVisibleAsUser(@NonNull Role role, @NonNull UserHandle user, + @NonNull Context context) { + return context.getResources().getBoolean(R.bool.config_showBrowserRole); + } } diff --git a/src/com/android/packageinstaller/role/model/DialerRoleBehavior.java b/src/com/android/packageinstaller/role/model/DialerRoleBehavior.java index 3831b0f7d..306bc0e21 100644 --- a/src/com/android/packageinstaller/role/model/DialerRoleBehavior.java +++ b/src/com/android/packageinstaller/role/model/DialerRoleBehavior.java @@ -72,4 +72,10 @@ public class DialerRoleBehavior implements RoleBehavior { public String getFallbackHolder(@NonNull Role role, @NonNull Context context) { return ExclusiveDefaultHolderMixin.getDefaultHolder(role, "config_defaultDialer", context); } + + @Override + public boolean isVisibleAsUser(@NonNull Role role, @NonNull UserHandle user, + @NonNull Context context) { + return context.getResources().getBoolean(R.bool.config_showDialerRole); + } } diff --git a/src/com/android/packageinstaller/role/model/SmsRoleBehavior.java b/src/com/android/packageinstaller/role/model/SmsRoleBehavior.java index d7ceae58a..2cd2080a4 100644 --- a/src/com/android/packageinstaller/role/model/SmsRoleBehavior.java +++ b/src/com/android/packageinstaller/role/model/SmsRoleBehavior.java @@ -27,6 +27,7 @@ import androidx.annotation.Nullable; import com.android.packageinstaller.permission.utils.CollectionUtils; import com.android.packageinstaller.role.utils.UserUtils; +import com.android.permissioncontroller.R; import java.util.List; @@ -79,4 +80,10 @@ public class SmsRoleBehavior implements RoleBehavior { return EncryptionUnawareConfirmationMixin.getConfirmationMessage(role, packageName, context); } + + @Override + public boolean isVisibleAsUser(@NonNull Role role, @NonNull UserHandle user, + @NonNull Context context) { + return context.getResources().getBoolean(R.bool.config_showSmsRole); + } } -- GitLab From 9956d911d675c6835251507b79390860acdc09a2 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Wed, 8 May 2019 15:54:43 -0700 Subject: [PATCH 632/701] Use the full permission label to avoid truncation in some locales. Fixes: 131630237 Fixes: 131837398 Test: View PermissionAppsFragment and AppPermissionFragment in English and Spanish. Change-Id: I9ac6dafb564566edfd9fe1b5ffd69a9137acdca3 --- .../packageinstaller/permission/model/PermissionApps.java | 7 +++++++ .../permission/ui/handheld/AppPermissionFragment.java | 4 ++-- .../permission/ui/handheld/PermissionAppsFragment.java | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/com/android/packageinstaller/permission/model/PermissionApps.java b/src/com/android/packageinstaller/permission/model/PermissionApps.java index b1f92e5d5..7d3a71761 100644 --- a/src/com/android/packageinstaller/permission/model/PermissionApps.java +++ b/src/com/android/packageinstaller/permission/model/PermissionApps.java @@ -56,6 +56,7 @@ public class PermissionApps { private final @Nullable AppDataCache mAppDataCache; private CharSequence mLabel; + private CharSequence mFullLabel; private Drawable mIcon; private @Nullable CharSequence mDescription; private List mPermApps; @@ -160,6 +161,10 @@ public class PermissionApps { return mLabel; } + public CharSequence getFullLabel() { + return mFullLabel; + } + public Drawable getIcon() { return mIcon; } @@ -327,6 +332,8 @@ public class PermissionApps { } } mLabel = info.loadLabel(mPm); + mFullLabel = info.loadSafeLabel(mPm, 0, + TextUtils.SAFE_STRING_FLAG_TRIM | TextUtils.SAFE_STRING_FLAG_FIRST_LINE); if (info.icon != 0) { mIcon = info.loadUnbadgedIcon(mPm); } else { diff --git a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java index 93045c536..d314bd73f 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionFragment.java @@ -144,7 +144,7 @@ public class AppPermissionFragment extends SettingsWithLargeHeader { if (mGroup != null) { getActivity().setTitle( getPreferenceManager().getContext().getString(R.string.app_permission_title, - mGroup.getLabel())); + mGroup.getFullLabel())); } } @@ -193,7 +193,7 @@ public class AppPermissionFragment extends SettingsWithLargeHeader { updateHeader(root.requireViewById(R.id.large_header)); ((TextView) root.requireViewById(R.id.permission_message)).setText( - context.getString(R.string.app_permission_header, mGroup.getLabel())); + context.getString(R.string.app_permission_header, mGroup.getFullLabel())); if (!Utils.isPermissionsHubEnabled()) { root.requireViewById(R.id.usage_summary).setVisibility(View.GONE); diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java index e9192ba27..70ea65a3f 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionAppsFragment.java @@ -171,7 +171,7 @@ public final class PermissionAppsFragment extends SettingsWithLargeHeader implem private static void bindUi(SettingsWithLargeHeader fragment, PermissionApps permissionApps, @NonNull String groupName) { final Drawable icon = permissionApps.getIcon(); - final CharSequence label = permissionApps.getLabel(); + final CharSequence label = permissionApps.getFullLabel(); fragment.setHeader(icon, label, null, null, true); fragment.setSummary(Utils.getPermissionGroupDescriptionString(fragment.getActivity(), -- GitLab From 8a67bd7bda1ef82e29cb0e24ca5fc956fdd14663 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Thu, 9 May 2019 10:19:40 -0700 Subject: [PATCH 633/701] Import translations. DO NOT MERGE Auto-generated-cl: translation import Bug: 64712476 Change-Id: I098ce971e2aff1dedbd745a70c19f98a2658bbe0 --- res/values-af/strings.xml | 4 ++- res/values-am/strings.xml | 4 ++- res/values-ar/strings.xml | 6 ++++- res/values-as/strings.xml | 6 ++++- res/values-az/strings.xml | 4 ++- res/values-b+sr+Latn/strings.xml | 6 +++-- res/values-be/strings.xml | 6 ++++- res/values-bg/strings.xml | 6 ++++- res/values-bn/strings.xml | 6 ++++- res/values-bs/strings.xml | 8 +++--- res/values-ca/strings.xml | 22 ++++++++-------- res/values-cs/strings.xml | 8 ++++-- res/values-da/strings.xml | 26 +++++++++++-------- res/values-de/strings.xml | 44 +++++++++++++++++--------------- res/values-el/strings.xml | 4 ++- res/values-en-rAU/strings.xml | 6 +++-- res/values-en-rCA/strings.xml | 6 +++-- res/values-en-rGB/strings.xml | 6 +++-- res/values-en-rIN/strings.xml | 6 +++-- res/values-en-rXC/strings.xml | 4 ++- res/values-es-rUS/strings.xml | 10 +++++--- res/values-es/strings.xml | 26 ++++++++++--------- res/values-et/strings.xml | 18 +++++++------ res/values-eu/strings.xml | 12 ++++++--- res/values-fa/strings.xml | 12 ++++++--- res/values-fi/strings.xml | 10 +++++--- res/values-fr-rCA/strings.xml | 10 +++++--- res/values-fr/strings.xml | 24 +++++++++-------- res/values-gl/strings.xml | 10 +++++--- res/values-gu/strings.xml | 6 ++++- res/values-hi/strings.xml | 8 ++++-- res/values-hr/strings.xml | 10 +++++--- res/values-hu/strings.xml | 6 ++++- res/values-hy/strings.xml | 6 ++++- res/values-in/strings.xml | 16 +++++++----- res/values-is/strings.xml | 4 ++- res/values-it/strings.xml | 8 +++--- res/values-iw/strings.xml | 6 ++++- res/values-ja/strings.xml | 8 ++++-- res/values-ka/strings.xml | 4 ++- res/values-kk/strings.xml | 14 ++++++---- res/values-km/strings.xml | 8 ++++-- res/values-kn/strings.xml | 6 ++++- res/values-ko/strings.xml | 12 ++++++--- res/values-ky/strings.xml | 18 ++++++++----- res/values-lo/strings.xml | 4 ++- res/values-lt/strings.xml | 6 ++++- res/values-lv/strings.xml | 6 ++++- res/values-mk/strings.xml | 6 +++-- res/values-ml/strings.xml | 6 ++++- res/values-mn/strings.xml | 8 ++++-- res/values-mr/strings.xml | 8 ++++-- res/values-ms/strings.xml | 6 ++++- res/values-my/strings.xml | 8 +++--- res/values-nb/strings.xml | 14 ++++++---- res/values-ne/strings.xml | 6 ++++- res/values-nl/strings.xml | 16 +++++++----- res/values-or/strings.xml | 16 +++++++----- res/values-pa/strings.xml | 6 ++++- res/values-pl/strings.xml | 44 +++++++++++++++++--------------- res/values-pt-rBR/strings.xml | 10 +++++--- res/values-pt-rPT/strings.xml | 12 +++++---- res/values-pt/strings.xml | 10 +++++--- res/values-ro/strings.xml | 8 ++++-- res/values-ru/strings.xml | 12 ++++++--- res/values-si/strings.xml | 4 ++- res/values-sk/strings.xml | 36 ++++++++++++++------------ res/values-sl/strings.xml | 42 +++++++++++++++--------------- res/values-sq/strings.xml | 14 ++++++---- res/values-sr/strings.xml | 6 +++-- res/values-sv/strings.xml | 4 ++- res/values-sw/strings.xml | 6 ++++- res/values-ta/strings.xml | 7 ++++- res/values-te/strings.xml | 6 ++++- res/values-th/strings.xml | 18 ++++++++----- res/values-tl/strings.xml | 6 ++++- res/values-tr/strings.xml | 16 +++++++----- res/values-uk/strings.xml | 20 +++++++++------ res/values-ur/strings.xml | 20 +++++++++------ res/values-uz/strings.xml | 16 +++++++----- res/values-vi/strings.xml | 6 ++++- res/values-zh-rCN/strings.xml | 6 ++++- res/values-zh-rHK/strings.xml | 36 ++++++++++++++------------ res/values-zh-rTW/strings.xml | 8 ++++-- res/values-zu/strings.xml | 6 ++++- 85 files changed, 616 insertions(+), 339 deletions(-) diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml index cb0cfb19c..296fcbada 100644 --- a/res/values-af/strings.xml +++ b/res/values-af/strings.xml @@ -210,7 +210,7 @@ 1 sekonde "Toestemmingonthounotas" - "%s gebruik jou ligging" + "%s het jou ligging op die agtergrond gekry" "Hierdie program het altyd toegang tot jou ligging. Tik om te verander." "Net terwyl die program gebruik word" "Geen toestemmings toegelaat nie" @@ -280,6 +280,8 @@ "Geen" "(Stelselverstek)" "Geen programme nie" + "Gekies" + "Gekies – %1$s" "spesiale programtoegang" "Spesiale programtoegang" "Geen spesiale programtoegang nie" diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml index c93ab9ef4..bcd7436d0 100644 --- a/res/values-am/strings.xml +++ b/res/values-am/strings.xml @@ -210,7 +210,7 @@ %s ሰከንዶች "የፈቃድ አስታዋሾች" - "%s የእርስዎን አካባቢ እየተጠቀመ ነበር" + "%s በበስተጀርባ አካባቢዎን አግኝተዋል" "ይህ መተግበሪያ በማንኛውም ጊዜ አካባቢዎን መድረስ ይችላል። ለመቀየር መታ ያድርጉ።" "መተግበሪያው በጥቅም ላይ እያለ ብቻ" "ምንም ፈቃዶች አልተፈቀዱም" @@ -280,6 +280,8 @@ "ምንም" "(የሥርዓት ነባሪ)" "መተግበሪያዎች የሉም" + "ተመርጧል" + "ተመርጧል - %1$s" "ልዩ የመተግበሪያ መዳረሻ" "ልዩ የመተግበሪያ መዳረሻ" "ምንም ልዩ መተግበሪያ መዳረሻ" diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml index 49e8d0478..9a6994156 100644 --- a/res/values-ar/strings.xml +++ b/res/values-ar/strings.xml @@ -238,7 +238,7 @@ ثانية واحدة "تذكيرات الأذونات" - "يستخدِم التطبيق %s موقعك الجغرافي." + "وضع %s الموقع الجغرافي لك في الخلفية" "يمكن لهذا التطبيق دائمًا الوصول إلى بيانات موقعك الجغرافي. انقر لتغيير ذلك." "أثناء استخدام التطبيق فقط" "لم يتم منح أي أذونات." @@ -308,6 +308,10 @@ "بدون" "(الإعداد التلقائي للنظام)" "ليست هناك تطبيقات." + + + + "أذونات خاصة للتطبيقات" "أذونات خاصة للتطبيقات" "لا إذن وصول خاص إلى التطبيق." diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml index 4b7cc71c8..18378f08b 100644 --- a/res/values-as/strings.xml +++ b/res/values-as/strings.xml @@ -210,7 +210,7 @@ %s ছেকেণ্ড "অনুমতি বিষয়ক ৰিমাইণ্ডাৰ" - "%sএ আপোনাৰ অৱস্থান ব্যৱহাৰ কৰি আছে" + "%sএ নেপথ্যত আপোনাৰ অৱস্থান লাভ কৰিছে" "এই এপটোৱে সদায় আপোনাৰ অৱস্থান এক্সেছ কৰিব পাৰে। সলনি কৰিবলৈ টিপক।" "কেৱল এপটো ব্যৱহাৰ হৈ থকা সময়ত" "কোনো অনুমতি দিয়া নাই" @@ -280,6 +280,10 @@ "নাই" "(ছিষ্টেম ডিফ\'ল্ট)" "কোনো এপ্‌ নাই" + + + + "বিশেষ এপ্ এক্সেছ" "বিশেষ এপ্ এক্সেছ" "কোনো বিশেষ এপ্ এক্সেছ নাই" diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml index c4e7d646d..f5fe6c7f9 100644 --- a/res/values-az/strings.xml +++ b/res/values-az/strings.xml @@ -210,7 +210,7 @@ 1 saniyə "İcazə xatırladıcıları" - "%s məkandan istifadə edir" + "%s arxa fonda məkanınıza daxil oldu" "Bu tətbiq daima məkana daxil ola bilər. Dəyişmək üçün klikləyin." "Yalnız tətbiqin istifadəsi zamanı" "İcazə verilmədi" @@ -280,6 +280,8 @@ "Yoxdur" "(Sistem defoltu)" "Tətbiq yoxdur" + "Seçilib" + "Seçilib - %1$s" "xüsusi tətbiq girişi" "Xüsusi tətbiq girişi" "Xüsusi tətbiq girişi yoxdur" diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml index 9c33836ab..d47e75f9f 100644 --- a/res/values-b+sr+Latn/strings.xml +++ b/res/values-b+sr+Latn/strings.xml @@ -60,7 +60,7 @@ "Nema aplikacija" "Podešavanja lokacije" "%1$s pruža usluge lokacije za ovaj uređaj. Pristup lokaciji možete da izmenite u podešavanjima lokacije." - "Ako odbijete ovu dozvolu, osnovne funkcije uređaja možda neće više funkcionisati ispravno." + "Ako odbijete ovu dozvolu, osnovne funkcije uređaja možda neće više ispravno raditi." "Primenjuje se u skladu sa smernicama" "Pristup u pozadini je onemogućen smernicama" "Pristup u pozadini je omogućen smernicama" @@ -217,7 +217,7 @@ %s sekundi "Podsetnici za dozvole" - "%s koristi vašu lokaciju" + "%s ima vašu lokaciju u pozadini" "Ova aplikacija može uvek da pristupa lokaciji. Dodirnite da biste to promenili." "Samo dok se aplikacija koristi" "Dozvole nisu odobrene" @@ -287,6 +287,8 @@ "Ništa" "(Podrazumevana sistemska)" "Nema aplikacija" + "Izabrano" + "Izabrano – %1$s" "pristup za specijalnu aplikaciju" "Pristup za spec. aplikaciju" "Nema pristupa za spec. apl." diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml index 95d3e06f1..af00f7da1 100644 --- a/res/values-be/strings.xml +++ b/res/values-be/strings.xml @@ -224,7 +224,7 @@ %s секунды "Напаміны пра дазволы" - "Праграма \"%s\" выкарыстоўвае даныя пра ваша месцазнаходжанне" + "%s атрымала доступ да даных месцазнаходжання ў фонавым рэжыме" "Гэта праграма заўсёды можа атрымаць доступ да даных пра ваша месцазнаходжанне. Націсніце, каб змяніць." "Толькі ў актыўным рэжыме праграмы" "Няма дазволаў" @@ -294,6 +294,10 @@ "Няма" "(Стандартная сістэмная)" "Няма праграм" + + + + "спецыяльны доступ да праграм" "Спецыяльны доступ да праграм" "Няма доступу да праграм" diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml index 2dc45da87..ed1ffa29a 100644 --- a/res/values-bg/strings.xml +++ b/res/values-bg/strings.xml @@ -210,7 +210,7 @@ 1 секунда "Напомняния за разрешения" - "%s използва местоположението ви" + "%s получи достъп до местоположението ви на заден план" "Приложението винаги има достъп до местоположението ви. Докоснете, за да промените това." "Само докато приложението се използва" "Няма позволени разрешения" @@ -280,6 +280,10 @@ "Няма" "(Стандартно за системата)" "Няма приложения" + + + + "специален достъп за приложението" "Специален достъп за прилож." "Няма спец. достъп за прилож." diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml index 4c14371f7..0ed2eb725 100644 --- a/res/values-bn/strings.xml +++ b/res/values-bn/strings.xml @@ -210,7 +210,7 @@ %s সেকেন্ড "অনুমতির রিমাইন্ডার" - "%s আপনার লোকেশনের ডেটা ব্যবহার করছে" + "%s ব্যাকগ্রাউন্ডে আপনার লোকেশনের ডেটা অ্যাক্সেস করেছে" "এই অ্যাপটি যেকোনও সময় আপনার লোকেশনের ডেটা অ্যাক্সেস করতে পারে। পরিবর্তন করতে ট্যাপ করুন।" "শুধুমাত্র অ্যাপ ব্যবহারের সময়" "কোনও অনুমতি নেই" @@ -280,6 +280,10 @@ "কোনওটিই নয়" "(সিস্টেম ডিফল্ট)" "কোনও অ্যাপ নেই" + + + + "অ্যাপের বিশেষ অ্যাক্সেস" "অ্যাপের বিশেষ অ্যাক্সেস" "অ্যাপের বিশেষ অ্যাক্সেস নেই" diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml index 197a1846c..0f4e9c8bb 100644 --- a/res/values-bs/strings.xml +++ b/res/values-bs/strings.xml @@ -17,7 +17,7 @@ "Kontroler odobrenja" - "UREDU" + "Uredu" "odobrenja" "Otkaži" "Aplikacija nije pronađena" @@ -122,7 +122,7 @@ %s aplikacija "Prikaži sve na kontrolnoj tabli" - "Filtrirano po: %1$s" + "Filtrirano prema: %1$s" "Prikaži sve na kontrolnoj tabli" "Filtriraj prema" "Filtriraj prema odobrenjima" @@ -217,7 +217,7 @@ %s sekundi "Podsjetnici odobrenja" - "Aplikacija %s je koristila vašu lokaciju" + "Aplikacija %s pristupa vašoj lokaciji u pozadini" "Ova aplikacija uvijek može pristupiti vašoj lokaciji. Dodirnite da promijenite." "Samo kada se aplikacija koristi" "Nijedno odobrenje nije dato" @@ -287,6 +287,8 @@ "Nema" "(Sistemski zadano)" "Nema aplikacija" + "Odabrano" + "Odabrano – %1$s" "poseban pristup aplikacijama" "Poseban pristup aplikacijama" "Nema pristupa posebnim apl." diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml index 5f5ba0ba8..0d5fc456a 100644 --- a/res/values-ca/strings.xml +++ b/res/values-ca/strings.xml @@ -129,7 +129,7 @@ "Amb més accessos" "Recents" "Ordena per ús de l\'aplicació" - "Ordena per temps" + "Ordena per hora" ", " "Actualitza" @@ -143,7 +143,7 @@ "Permet sempre" "Permet mentre s\'utilitza l\'aplicació" "Denega" - "Permís per accedir a %1$s" + "Permís d\'accés a %1$s" "Accés a %1$s per a aquesta aplicació" "%1$s ha accedit fa %3$s a: %2$s" "%1$s ha accedit a l\'activitat física fa %2$s" @@ -186,7 +186,7 @@ "Les aplicacions amb aquest permís poden accedir a les fotos, al contingut multimèdia i als fitxers del dispositiu" "Últim accés: %1$s" "Actualment denegat / Últim accés: %1$s" - "No hi ha accedit mai" + "No s\'hi ha accedit mai" "Denegat / No hi ha accedit mai" "Permès" "Permès sempre" @@ -210,7 +210,7 @@ 1 segon "Recordatoris de permisos" - "%s ha estat utilitzant la teva ubicació" + "%s ha obtingut la teva ubicació en segon pla" "Aquesta aplicació pot accedir a la teva ubicació en qualsevol moment. Toca per canviar-ho." "Només mentre s\'utilitza l\'aplicació" "No s\'ha concedit cap permís" @@ -233,7 +233,7 @@ "Vols establir %1$s com a aplicació de navegador predeterminada?" "No calen permisos" "Aplicació Telèfon predeterminada" - "Aplicació Telèfon" + "Aplicació de telèfon" "Aplicacions que et permeten fer i rebre trucades al dispositiu" "Vols establir %1$s com a aplicació de telèfon predeterminada?" "Tindrà accés al registre de trucades i podrà enviar SMS" @@ -249,7 +249,7 @@ "No calen permisos" "Aplicació d\'inici predeterminada" "Aplicació d\'inici" - "Aplicacions, o sovint anomenades \"menú d\'aplicacions\", que reemplacen les pantalles d\'inici del dispositiu Android i et donen accés al contingut i funcions del teu dispositiu" + "Aplicacions, sovint anomenades \"menú d\'aplicacions\", que reemplacen les pantalles d\'inici del dispositiu Android i et donen accés al contingut i funcions del teu dispositiu" "Vols establir %1$s com a aplicació d\'inici predeterminada?" "No calen permisos" "Aplicació predeterminada per redirigir trucades" @@ -257,10 +257,10 @@ "Aplicacions que et permeten desviar trucades a altres números de telèfon" "Vols establir %1$s com a aplicació de desviació de trucades predeterminada?" "No calen permisos" - "App predeterminada per identificar i filtrar trucades brossa" - "Aplicació per identificar i filtrar trucades brossa" + "App predeterminada ID trucades i filtre trucades brossa" + "Aplicació ID trucades i filtre trucades brossa" "Aplicacions que et permeten identificar les trucades entrants, bloquejar les trucades brossa i automàtiques, afegir els números que no vulguis que et truquin a una llista negra, entre d\'altres" - "Vols establir %1$s com a aplicació predeterminada per identificar i filtrar trucades brossa?" + "Vols establir %1$s com a aplicació predeterminada per identificar trucades i filtrar trucades brossa?" "No calen permisos" "Predeterminada actualment" "No m\'ho tornis a preguntar" @@ -278,8 +278,10 @@ "Obertura d\'enllaços" "Predeterminada per a la feina" "Cap" - "(Opció predetermina del sistema)" + "(Opció predeterminada del sistema)" "Cap aplicació" + "Seleccionada" + "Seleccionada: %1$s" "accés especial d\'aplicacions" "Accés especial d\'aplicacions" "Sense accés especial d\'apps" diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml index ceaddea27..d1bb3db0a 100644 --- a/res/values-cs/strings.xml +++ b/res/values-cs/strings.xml @@ -178,7 +178,7 @@ "Údaje o posledním přístupu momentálně nejsou v rámci tohoto oprávnění dostupné" "Zobrazit všechna oprávnění aplikace %1$s" "Zobrazit všechny aplikace s tímto oprávněním" - "Aplikace s tímto oprávněním mohou %1$s" + "Aplikace s tímto oprávněním mohou: %1$s" "Aplikace s tímto oprávněním mají přístup k vaší fyzické aktivitě, jako je chůze, jízda na kole, jízda autem, počet kroků a další" "Aplikace s tímto oprávněním mají přístup ke kalendáři" "Aplikace s tímto oprávněním mohou číst a zapisovat do seznamu hovorů v telefonu" @@ -224,7 +224,7 @@ 1 sekunda "Připomenutí o oprávněních" - "Aplikace %s využívá vaši polohu" + "%s má přístup k poloze na pozadí" "Tato aplikace má neomezený přístup k poloze. Klepnutím to změníte." "Jen během používání aplikace" "Nejsou povolena žádná oprávnění" @@ -294,6 +294,10 @@ "Žádné" "(Výchozí nastavení systému)" "Žádné aplikace" + + + + "přístup ke speciálním aplikacím" "Přístup ke spec. aplikacím" "Žádný přístup ke spec. aplik." diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml index 4b4cadedc..7f4eeae23 100644 --- a/res/values-da/strings.xml +++ b/res/values-da/strings.xml @@ -96,7 +96,7 @@ "Seneste adgang: %1$s\nSeneste adgang, da appen var i brug" "Seneste adgang: %1$s\nSenest anvendt i baggrunden" "Alle tilladelser" - "Når som helst" + "Nogensinde" "De seneste 7 dage" "De seneste 24 timer" "Den seneste time" @@ -109,12 +109,12 @@ "Seneste adgang den seneste time" "Seneste adgang i de sidste 15 minutter" "Seneste adgang det seneste minut" - "Brug af tilladelse nogensinde" - "Brug af tilladelse i de sidste 7 dage" - "Brug af tilladelse i de sidste 24 timer" - "Brug af tilladelse den seneste time" - "Brug af tilladelse i de sidste 15 minutter" - "Brug af tilladelse det seneste minut" + "Anvendte tilladelser nogensinde" + "Anvendte tilladelser i de sidste 7 dage" + "Anvendte tilladelser i de sidste 24 timer" + "Anvendte tilladelser den seneste time" + "Anvendte tilladelser i de sidste 15 minutter" + "Anvendte tilladelser det seneste minut" %s app %s apps @@ -173,7 +173,7 @@ "Se alle tilladelser for %1$s" "Se alle apps med denne tilladelse" "Apps med denne tilladelse kan %1$s" - "Apps med denne tilladelse har adgang til dine fysiske aktiviteter, f.eks. hvor meget du har gået, cyklet eller kørt, skridttæller og meget mere" + "Apps med denne tilladelse har adgang til dine fysiske aktiviteter, f.eks. hvor meget du har gået, cyklet eller kørt, skridttæller m.m." "Apps med denne tilladelse kan få adgang til din kalender" "Apps med denne tilladelse kan læse og redigere telefonens opkaldsliste" "Apps med denne tilladelse kan tage billeder og optage video" @@ -210,7 +210,7 @@ %s sekunder "Påmindelser om tilladelse" - "%s har anvendt din placering" + "%s har din placering i baggrunden" "Denne app kan altid få adgang til din placering. Tryk for at ændre denne indstilling." "Kun mens appen er i brug" "Der ikke givet nogen tilladelser" @@ -280,6 +280,10 @@ "Ingen" "(Systemstandard)" "Ingen apps" + + + + "særlig appadgang" "Særlig appadgang" "Ingen særlig appadgang" @@ -297,8 +301,8 @@ "Afvis" "Avancerede indstillinger" "Avancerede indstillinger" - "Vis brugen af systemapps" - "Vis systemapps anvendelse af tilladelser på statusbjælken, i betjeningspanelet og andre steder" + "Vis brug af systemapps" + "Vis systemapps\' anvendelse af tilladelser på statusbjælken, i betjeningspanelet og andre steder" "Fremhæv brugen af følgende" "Vis aktiveringsregistrering for Assistent" "Vis ikon på statusbjælken, når mikrofonen bruges til at aktivere taleassistenten" diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index 8e92f4f98..72e38fc1f 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -38,7 +38,7 @@ "Keine deaktiviert" "Zulassen" "Immer zulassen" - "Nur bei aktueller Verwendung der App zulassen" + "Zugriff nur während der Nutzung der App zulassen" "Immer zulassen" "Apps" "App-Berechtigungen" @@ -73,7 +73,7 @@ "Immer zulassen" - "Nur bei aktueller Verwendung der App zulassen" + "Zugriff nur während der Nutzung der App zulassen" "Ablehnen" "Wird geladen…" "Alle Berechtigungen" @@ -93,8 +93,8 @@ "App wird vorbereitet…" "Unbekannt" "Dashboard" - "Letzter Zugriff: %1$s\nLetzter Zugriff bei Verwendung der App" - "Letzter Zugriff: %1$s\nLetzter Zugriff im Hintergrund" + "Letzter Zugriff: %1$s\nZugriff erfolgte bei Nutzung der App" + "Letzter Zugriff: %1$s\nZugriff erfolgte im Hintergrund" "Alle Berechtigungen" "Beliebiger Zeitraum" "Letzte 7 Tage" @@ -119,9 +119,9 @@ %s Apps 1 App - "Alle im Dashboard aufrufen" + "Alle im Dashboard ansehen" "Gefiltert nach: %1$s" - "Alle Nutzungen im Dashboard ansehen" + "Alle im Dashboard ansehen" "Filterkriterium" "Nach Berechtigungen filtern" "Nach Zeitraum filtern" @@ -141,10 +141,10 @@ "Zugriff: %1$s Mal. Zuletzt verwendet vor %2$s" "Zulassen" "Immer zulassen" - "Nur bei aktueller Verwendung der App zulassen" + "Zugriff nur während der Nutzung der App zulassen" "Ablehnen" "Berechtigung \"%1$s\"" - "\"%1$s\"-Zugriff für diese App" + "Darf diese App auf \"%1$s\" zugreifen?" "%1$s hat vor %3$s die Berechtigung \"%2$s\" genutzt" "%1$s hat vor %2$s auf deine körperliche Aktivität zugegriffen" "%1$s hat vor %2$s auf deinen Kalender zugegriffen" @@ -169,8 +169,8 @@ "%1$s hat nicht auf deine Sensoren zugegriffen" "%1$s hat nicht auf deine SMS zugegriffen" "%1$s hat nicht auf deinen Speicher zugegriffen" - "Daten zum letzten Zugriff sind derzeit nicht für diese Berechtigung verfügbar" - "Alle %1$s-Berechtigungen anzeigen" + "Für diese Berechtigung sind zurzeit keine Angaben zum letzten Zugriff verfügbar" + "Alle Berechtigungen von %1$s anzeigen" "Alle Apps mit dieser Berechtigung anzeigen" "Apps mit dieser Berechtigung dürfen %1$s" "Apps mit dieser Berechtigung können auf Daten zu deiner körperlichen Aktivität, wie Gehen, Radfahren und Autofahren, und auf deine Schrittzahlwerte zugreifen" @@ -186,12 +186,12 @@ "Apps mit dieser Berechtigung können auf Fotos, Medien und Dateien auf deinem Gerät zugreifen" "Letzter Zugriff: %1$s" "Zurzeit nicht zugelassen/Letzter Zugriff: %1$s" - "Nie auf Berechtigung zugegriffen" - "Abgelehnt/Nie auf Berechtigung zugegriffen" - "Zugelassen" - "Immer zugelassen" - "Nur bei aktueller Verwendung zugelassen" - "Abgelehnt" + "Bisher kein Zugriff auf diese Berechtigung" + "Abgelehnt/Kein Zugriff auf diese Berechtigung" + "Zugriff zugelassen" + "Zugriff immer zugelassen" + "Zugriff nur während Nutzung zugelassen" + "Zugriff abgelehnt" "Detaillierte Nutzungen ansehen" %s Tage @@ -210,13 +210,13 @@ 1 Sekunde "Berechtigungserinnerungen" - "%s hat deinen Standort verwendet" + "%s greift im Hintergrund auf deinen Standort zu" "Diese App kann immer auf deinen Standort zugreifen. Zum Ändern hier tippen." "Nur während die App verwendet wird" "Keine Berechtigungen zugelassen" "Alle Berechtigungen zugelassen" "Keine Apps zugelassen" - "Keine Apps abgelehnt" + "Zugriff für keine Apps abgelehnt" "Einstellungen" "%s hat uneingeschränkten Zugriff auf dein Gerät" "%s Bedienungshilfen-Apps haben uneingeschränkten Zugriff auf dein Gerät" @@ -233,12 +233,12 @@ "%1$s als Standard-Browser-App festlegen?" "Keine Berechtigungen erforderlich" "Standard-Telefonie-App" - "Telefon App" + "Telefon-App" "Apps, mit denen du dein Gerät zum Telefonieren benutzen kannst" "%1$s als Standard-App zum Telefonieren festlegen?" "Kann auf Anrufliste zugreifen und SMS versenden" "Standard-SMS-App" - "SMS App" + "SMS-App" "Apps, mit denen du über deine Telefonnummer SMS, Fotos, Videos und mehr senden und empfangen kannst" "%1$sals Standard-SMS-App festlegen?" "Kann auf Kontakte, SMS und Telefon zugreifen" @@ -259,7 +259,7 @@ "Keine Berechtigungen erforderlich" "Standard-App für Anrufer-ID und Spam" "Anrufer-ID- und Spam-App" - "Apps, mit denen du u. a. eingehende Anrufe erkennen, Spam- und automatisierte Anrufe blockieren und unerwünschte Nummern auf die schwarze Liste setzen kannst" + "Apps, mit denen du u. a. eingehende Anrufe erkennen, Spam- und automatisierte Anrufe blockieren und unerwünschte Nummern sperren kannst" "%1$s als standardmäßige Anrufer-ID- und Spam-App festlegen?" "Keine Berechtigungen erforderlich" "Aktueller Standard" @@ -280,6 +280,8 @@ "Keine App" "(Systemstandardeinstellung)" "Keine Apps" + "Ausgewählt" + "Ausgewählt – %1$s" "spezieller App-Zugriff" "Spezieller App-Zugriff" "Kein spezieller App-Zugriff" diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml index 48f0bdecc..5169e0889 100644 --- a/res/values-el/strings.xml +++ b/res/values-el/strings.xml @@ -210,7 +210,7 @@ 1 δευτερόλεπτο "Υπενθυμίσεις άδειας" - "Η εφαρμογή %s χρησιμοποιεί την τοποθεσία σας" + "Η εφαρμογή %s έλαβε την τοποθεσία σας στο παρασκήνιο" "Αυτή η εφαρμογή μπορεί να έχει πάντα πρόσβαση στην τοποθεσία σας. Πατήστε για να αλλάξετε τη ρύθμιση." "Μόνο κατά τη χρήση της εφαρμογής" "Δεν επιτρέπονται άδειες" @@ -280,6 +280,8 @@ "Καμία" "(Προεπιλογή συστήματος)" "Δεν υπάρχουν εφαρμογές" + "Επιλέχτηκε" + "Επιλέχτηκε - %1$s" "ειδική πρόσβαση στην εφαρμογή" "Ειδική άδεια εφαρμογής" "Χωρίς ειδική άδεια εφαρμογής" diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml index 5a7758312..2bcbdaad7 100644 --- a/res/values-en-rAU/strings.xml +++ b/res/values-en-rAU/strings.xml @@ -175,7 +175,7 @@ "Apps with this permission can %1$s" "Apps with this permission can access your physical activity, such as walking, cycling, driving, step count and more" "Apps with this permission can access your calendar" - "Apps with this permission can read and write phone call log" + "Apps with this permission can read and write phone call logs" "Apps with this permission can take pictures and record video" "Apps with this permission can access your contacts" "Apps with this permission can access this device\'s location" @@ -210,7 +210,7 @@ 1 second "Permission reminders" - "%s has been using your location" + "%s got your location in the background" "This app can always access your location. Tap to change." "Only while app is in use" "No permissions allowed" @@ -280,6 +280,8 @@ "None" "(System default)" "No apps" + "Selected" + "Selected – %1$s" "special app access" "Special app access" "No special app access" diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml index 5a7758312..2bcbdaad7 100644 --- a/res/values-en-rCA/strings.xml +++ b/res/values-en-rCA/strings.xml @@ -175,7 +175,7 @@ "Apps with this permission can %1$s" "Apps with this permission can access your physical activity, such as walking, cycling, driving, step count and more" "Apps with this permission can access your calendar" - "Apps with this permission can read and write phone call log" + "Apps with this permission can read and write phone call logs" "Apps with this permission can take pictures and record video" "Apps with this permission can access your contacts" "Apps with this permission can access this device\'s location" @@ -210,7 +210,7 @@ 1 second "Permission reminders" - "%s has been using your location" + "%s got your location in the background" "This app can always access your location. Tap to change." "Only while app is in use" "No permissions allowed" @@ -280,6 +280,8 @@ "None" "(System default)" "No apps" + "Selected" + "Selected – %1$s" "special app access" "Special app access" "No special app access" diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml index 5a7758312..2bcbdaad7 100644 --- a/res/values-en-rGB/strings.xml +++ b/res/values-en-rGB/strings.xml @@ -175,7 +175,7 @@ "Apps with this permission can %1$s" "Apps with this permission can access your physical activity, such as walking, cycling, driving, step count and more" "Apps with this permission can access your calendar" - "Apps with this permission can read and write phone call log" + "Apps with this permission can read and write phone call logs" "Apps with this permission can take pictures and record video" "Apps with this permission can access your contacts" "Apps with this permission can access this device\'s location" @@ -210,7 +210,7 @@ 1 second "Permission reminders" - "%s has been using your location" + "%s got your location in the background" "This app can always access your location. Tap to change." "Only while app is in use" "No permissions allowed" @@ -280,6 +280,8 @@ "None" "(System default)" "No apps" + "Selected" + "Selected – %1$s" "special app access" "Special app access" "No special app access" diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml index 5a7758312..2bcbdaad7 100644 --- a/res/values-en-rIN/strings.xml +++ b/res/values-en-rIN/strings.xml @@ -175,7 +175,7 @@ "Apps with this permission can %1$s" "Apps with this permission can access your physical activity, such as walking, cycling, driving, step count and more" "Apps with this permission can access your calendar" - "Apps with this permission can read and write phone call log" + "Apps with this permission can read and write phone call logs" "Apps with this permission can take pictures and record video" "Apps with this permission can access your contacts" "Apps with this permission can access this device\'s location" @@ -210,7 +210,7 @@ 1 second "Permission reminders" - "%s has been using your location" + "%s got your location in the background" "This app can always access your location. Tap to change." "Only while app is in use" "No permissions allowed" @@ -280,6 +280,8 @@ "None" "(System default)" "No apps" + "Selected" + "Selected – %1$s" "special app access" "Special app access" "No special app access" diff --git a/res/values-en-rXC/strings.xml b/res/values-en-rXC/strings.xml index 966c154aa..ed4e15c4d 100644 --- a/res/values-en-rXC/strings.xml +++ b/res/values-en-rXC/strings.xml @@ -210,7 +210,7 @@ ‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‏‎‏‎‏‎‎‏‎‏‎‎‎‎‏‎‏‎‏‎‎‎‏‎‏‏‎‏‎‎‎‎‏‏‏‏‎‏‎‎‎‏‎‏‏‎‎‎‎‏‎‏‏‏‎‏‎1 second‎‏‎‎‏‎ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‎‏‏‎‎‏‎‏‎‏‏‏‏‏‎‏‎‏‏‏‎‏‎‏‏‎‏‏‎‏‎‏‏‎‏‎‏‎‎‎‎‏‎‎‎‎‎‎‏‏‏‏‎Permission reminders‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‎‏‎‏‎‏‎‎‏‎‎‏‏‏‏‎‏‏‎‏‏‏‎‎‏‎‎‎‎‎‎‎‏‎‎‎‎‏‎‎‏‎‏‏‏‎‏‏‏‎‏‎‏‏‏‎‎‎‏‎‎‏‏‎%s‎‏‎‎‏‏‏‎ has been using your location‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‎‏‎‏‏‎‏‏‏‎‎‎‏‎‎‎‎‏‎‏‎‏‏‎‏‎‏‎‏‎‏‏‏‎‏‏‎‎‎‏‏‏‏‎‎‏‎‎‎‏‏‎‏‎‎‏‎‎‏‎‎‏‏‎%s‎‏‎‎‏‏‏‎ got your location in the background‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‏‎‏‏‏‎‎‏‎‏‎‏‏‎‎‏‎‏‏‎‏‎‎‎‏‎‏‎‏‎‎‎‎‎‎‎‎‏‎‎‎‏‏‎‎‎‏‎‎‏‏‏‎‎‎This app can always access your location. Tap to change.‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‎‎‎‎‏‏‎‎‎‏‎‎‏‎‏‎‏‎‎‏‏‎‎‎‏‎‏‎‏‎‏‎‎‏‎‏‏‏‏‏‎‏‏‏‏‏‏‎‎‎‎‏‏‎‏‏‎Only while app is in use‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‎‏‏‏‎‏‏‎‎‏‏‏‎‏‎‎‎‏‎‎‏‏‎‏‏‎‎‏‏‏‎‎‎‏‎‏‎‎‏‎‏‎‏‎‎‎‎‏‏‎‎‏‎‎‏‎No permissions allowed‎‏‎‎‏‎" @@ -280,6 +280,8 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‏‏‎‏‎‏‎‎‏‏‎‏‏‎‏‏‎‎‎‏‏‏‎‎‏‎‏‎‎‎‏‎‎‏‏‎‏‏‎‏‏‎‏‏‏‎‎‎‎‎‏‎‏‎‎None‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‏‏‎‏‎‏‏‎‏‏‏‎‎‏‏‎‏‏‎‏‎‎‏‏‏‎‏‏‎‎‏‏‏‎‎‏‎‎‏‎‎‏‏‏‏‎‏‎‎‎‎‏‎‎‎(System default)‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‏‎‏‏‎‎‎‎‎‏‎‎‏‏‏‎‏‎‎‏‏‎‏‏‏‏‏‏‏‎‎‏‏‎‏‎‎‎‎‎‏‏‎‏‎‏‎‏‎‏‎‏‏‏‎No apps‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‎‎‎‎‏‎‏‎‏‎‏‏‏‏‏‎‎‏‏‎‏‎‏‏‎‎‎‎‏‏‎‎‎‏‏‎‏‏‎‎‎‏‏‎‏‎‎‏‏‏‎‎‏‏‎‏‎Selected‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‏‎‏‎‏‎‎‏‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‏‏‏‎‏‏‏‎‏‏‎‎‏‎‎‏‎‎‎‏‎‏‏‎‏‏‏‎‏‏‎Selected - ‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‎‏‏‎‏‎‎‏‎‏‏‎‎‎‎‏‏‏‎‏‏‏‏‎‏‎‎‎‎‏‎‎‎‎‏‎‏‏‎‎‎‏‎‏‏‏‏‎‎‏‎‎‏‎‏‎‎special app access‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎‎‎‏‏‎‎‏‏‏‎‎‏‎‎‏‏‏‎‎‏‎‎‎‏‎‏‏‎‏‏‎‎‎‏‏‏‏‏‎‎‎‏‎‎‎‏‏‏‏‎‏‏‎‏‎Special app access‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‏‏‎‎‏‏‏‎‏‏‎‏‏‏‏‎‏‏‏‎‏‎‏‎‏‎‎‎‏‏‏‎‏‏‎‎‎‏‎‏‎‎‏‎‏‎‎‏‏‏‎‏‎‎‏‏‎No special app access‎‏‎‎‏‎" diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml index 395acd0c1..fa0de8c04 100644 --- a/res/values-es-rUS/strings.xml +++ b/res/values-es-rUS/strings.xml @@ -173,7 +173,7 @@ "Ver todos los permisos de %1$s" "Ver todas las apps que tienen este permiso" "Las apps con este permiso pueden %1$s" - "Las apps que tienen este permiso pueden acceder a tu actividad física, recorridos a pie o en bicicleta, trayectos en coche, recuento de pasos y mucho más" + "Las apps que tienen este permiso pueden acceder a tu actividad física, recorridos a pie o en bicicleta, trayectos en automóvil, recuento de pasos y mucho más" "Las apps con este permiso pueden acceder a tu calendario" "Las apps que tienen este permiso pueden leer el registro de llamadas del teléfono y escribir en él" "Las apps que tienen este permiso pueden tomar fotos y grabar videos" @@ -210,7 +210,7 @@ 1 segundo "Recordatorios de permisos" - "%s ha estado usando tu ubicación" + "%s accedió a tu ubicación en segundo plano" "Esta app puede acceder a tu ubicación en todo momento. Presiona para cambiar el permiso." "Solo cuando la app está en uso" "No se otorgó ningún permiso" @@ -227,7 +227,7 @@ "Las aplicaciones de asistencia pueden brindarte ayuda en función de la pantalla que estás viendo. Para ofrecerte asistencia integrada, algunas aplicaciones son compatibles con los servicios de selector y entrada de voz." "¿Quieres establecer %1$s como tu aplicación de asistencia predeterminada?" "Obtiene acceso a los SMS y al registro de llamadas" - "App navegador predeterminada" + "Navegador predet." "App de navegador" "Apps que te permiten acceder a Internet y mostrar los vínculos que presionas" "¿Quieres establecer %1$s como tu app de navegador predeterminada?" @@ -280,6 +280,10 @@ "Ninguna" "(Predeterminada de sistema)" "Sin apps" + + + + "Acceso especial a apps" "Acceso especial a apps" "No hay acceso especial a apps" diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index bcc7b9301..18579511f 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -53,7 +53,7 @@ "Esta aplicación está diseñada para una versión anterior de Android. Si se le deniega el permiso, puede dejar de funcionar de la forma prevista." "realizar una acción desconocida" - "%1$d de %2$d aplicaciones permitidas" + "%1$d de %2$d aplicaciones con el permiso" "Mostrar aplicaciones del sistema" "Ocultar aplicaciones del sistema" "No hay aplicaciones" @@ -169,7 +169,7 @@ "%1$s no ha accedido a tus sensores" "%1$s no ha accedido a tus SMS" "%1$s no ha accedido a tu almacenamiento" - "Los datos del último acceso de este permiso no está disponibles ahora mismo" + "Los datos del último acceso de este permiso no están disponibles ahora mismo" "Ver todos los permisos de %1$s" "Ver todas las aplicaciones con este permiso" "Las aplicaciones con este permiso pueden %1$s" @@ -181,16 +181,16 @@ "Las aplicaciones que tengan este permiso pueden acceder a la ubicación del dispositivo" "Las aplicaciones que tengan este permiso pueden grabar audio" "Las aplicaciones que tengan este permiso pueden hacer y gestionar llamadas de teléfono" - "Las aplicaciones que tengan este permiso pueden acceder a los datos de sensores sobre tus constantes vitales" + "Las aplicaciones que tengan este permiso pueden acceder a los datos de los sensores sobre tus constantes vitales" "Las aplicaciones que tengan este permiso pueden ver y enviar mensajes SMS" "Las aplicaciones con este permiso pueden acceder a fotos, contenido multimedia y archivos de tu dispositivo" "Último acceso: %1$s" "Actualmente denegado / Último acceso: %1$s" - "No se ha accedido nunca" - "Denegado / No se ha accedido nunca" + "No ha accedido nunca" + "Denegado / Último acceso: Nunca" "Permitido" "Permitido siempre" - "Solo se permite mientras se usa" + "Permitido solo mientras se usa" "Denegado" "Ver uso detallado" @@ -210,7 +210,7 @@ 1 segundo "Recordatorios de permisos" - "%s ha estado usando tu ubicación" + "%s ha obtenido tu ubicación en segundo plano" "Esta aplicación puede acceder siempre a tu ubicación. Toca para cambiarlo." "Solo mientras la aplicación está en uso" "No se ha concedido ningún permiso" @@ -227,12 +227,12 @@ "Las aplicaciones de asistencia te ayudan según la información que aparece en la pantalla. Algunas aplicaciones admiten tanto el menú de aplicaciones como los servicios de entrada de voz para ofrecerte asistencia integrada." "¿Quieres establecer %1$s como tu aplicación de asistencia predeterminada?" "Accede a los SMS, al registro de llamadas" - "App de navegador predet." + "Aplicación de navegador pred." "Aplicación de navegador" "Son aplicaciones que te permiten acceder a Internet y te muestran los enlaces que tocas" "¿Quieres configurar %1$s como tu aplicación de navegador predeterminada?" "No se necesita ningún permiso" - "App teléfono predeterminada" + "Aplicación de teléfono predet." "Aplicación de teléfono" "Son las aplicaciones que te permiten hacer y recibir llamadas de teléfono en tu dispositivo" "¿Quieres establecer a %1$s como tu aplicación de teléfono predeterminada?" @@ -249,7 +249,7 @@ "No se necesita ningún permiso" "Aplicación de inicio predet." "Aplicación de inicio" - "Los launchers reemplazan las pantallas de inicio en tu dispositivo Android y te dan acceso a contenido y funciones de tu dispositivo" + "Estas aplicaciones, también conocidas como launchers, reemplazan las pantallas de inicio en tu dispositivo Android y te dan acceso a contenido y funciones de tu dispositivo" "¿Quieres establecer a %1$s como tu aplicación de inicio predeterminada?" "No se necesita ningún permiso" "App redirección llamadas predet." @@ -280,6 +280,8 @@ "Ninguno" "(Predeterminada del sistema)" "No hay aplicaciones" + "Seleccionada" + "Seleccionada: %1$s" "acceso especial de apps" "Acceso especial de apps" "Sin acceso especial de apps" @@ -299,8 +301,8 @@ "Ajustes avanzados" "Mostrar el uso de las aplicaciones del sistema" "Mostrar el uso de permisos de las aplicaciones del sistema en la barra de estado, el panel de control y otros sitios" - "Destacar el uso de estas opciones" + "Destacar el uso de estas aplicaciones" "Mostrar la detección de activación del Asistente" - "Mostrar icono en la barra de estado cuando se utilice el micrófono para activar la función Asistente de voz" + "Mostrar icono en la barra de estado cuando se utilice el micrófono para activar el asistente de voz" "¿Quieres permitir que <b>%1$s</b> acceda a las fotos y archivos multimedia del dispositivo?" diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml index cb7bb883b..abea81cf0 100644 --- a/res/values-et/strings.xml +++ b/res/values-et/strings.xml @@ -143,10 +143,10 @@ "Luba alati" "Luba rakenduse kasutamise ajal" "Keela" - "Luba %1$s" - "Üksuse %1$s juurdepääs sellele rakendusele" - "Rakendus %1$s pääses teie loale %2$s juurde %3$s tagasi" - "Rakendus %1$s pääses teie füüsilist. tegevustele juurde %2$s tagasi" + "Funktsiooni %1$s luba" + "Funktsiooni %1$s juurdepääs sellele rakendusele" + "Rakendus %1$s pääses funktsioonile %2$s ligi %3$s tagasi" + "Rakendus %1$s pääses teie füüsilisele tegevustele juurde %2$s tagasi" "Rakendus %1$s pääses teie kalendrile juurde %2$s tagasi" "Rakendus %1$s pääses teie kõnelogidele juurde %2$s tagasi" "Rakendus %1$s pääses teie kaamerale juurde %2$s tagasi" @@ -186,7 +186,7 @@ "Selle loaga rakendused pääsevad teie seadmes juurde fotodele, meediale ja failidele" "Viimane juurdepääs: %1$s" "Praegu keelatud / viimane juurdepääs: %1$s" - "Pole kunagi juurde pääsetud" + "Pole kunagi juurde pääsenud" "Keelatud / pole kunagi juurde pääsetud" "Lubatud" "Alati lubatud" @@ -210,7 +210,7 @@ 1 sekund "Loa meeldetuletused" - "%s on kasutanud teie asukohta" + "%s sai taustal teie asukoha" "See rakendus pääseb teie asukohale alati juurde. Puudutage muutmiseks." "Ainult rakenduse kasutamise ajal" "Ühtegi luba pole antud" @@ -237,8 +237,8 @@ "Rakendused, mis võimaldavad teil seadmes telefonikõnesid teha ja vastu võtta" "Kas soovite määrata rakenduse %1$s telefoni vaikerakenduseks?" "Saab juurdepääsu kõnelogidele ja saata SMS-e" - "SMS-i vaikerakendus" - "SMS-i rakendus" + "SMS-vaikerakendus" + "SMS-rakendus" "Rakendused, millel on luba kasutada teie telefoninumbrit lühisõnumite, fotode, videote jms saatmiseks ja vastuvõtmiseks" "Kas soovite määrata rakenduse %1$s SMS-i vaikerakenduseks?" "Saab juurdepääsu kontaktidele, SMS-idele, telefonile" @@ -280,6 +280,8 @@ "Puudub" "(Süsteemi vaikeseade)" "Rakendusi pole" + "Valitud" + "Valitud – %1$s" "rakenduste erijuurdepääs" "Rakenduste erijuurdepääs" "Rakenduse erijuurdepääs puudub" diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml index 9754acd0f..26d209374 100644 --- a/res/values-eu/strings.xml +++ b/res/values-eu/strings.xml @@ -105,7 +105,7 @@ "Ez da eskatu baimenik" "Orain arteko azken sarbidea" "Azken zazpi egunetako azken sarbidea" - "Azken 24 orduetako azken sarbidea" + "Azken 24 orduetan erabilitakoak" "Azken ordubeteko azken sarbidea" "Azken 15 minutuetako azken sarbidea" "Azken minutuko azken sarbidea" @@ -210,7 +210,7 @@ 1 segundo "Baimenen abisuak" - "%s zure kokapena erabiltzen aritu da" + "%s aplikazioak kokapena atzitu du atzeko planoan" "Aplikazio honek beti atzi dezake kokapena. Sakatu aldatzeko." "Aplikazioa erabiltzen ari zarenean soilik" "Ez zaio eman baimenik" @@ -280,6 +280,10 @@ "Bat ere ez" "(Sistemaren aplikazio lehenetsia)" "Ez dago aplikaziorik" + + + + "aplikazio-baimen bereziak" "Aplikazio-baimen bereziak" "Ez dago aplikazio-baimen berezirik" @@ -298,9 +302,9 @@ "Ezarpen aurreratuak" "Ezarpen aurreratuak" "Erakutsi sistema-aplikazioen erabilera" - "Erakutsi sistema-aplikazioak baimenak nola erabiltzen dituen egoera-barran, panelean eta dagokion toki guztietan" + "Erakutsi egoera-barran sistema-aplikazioek nola erabiltzen dituzten baimenak, panelean eta dagokion toki guztietan" "Nabarmendu hauen erabilera" - "Erakutsi Laguntzailea abiarazi behar dela hauteman den" + "Erakutsi Laguntzailea abiarazteko hautematea" "Mikrofonoa erabiltzen denean ahozko laguntza aktibatzeko, erakutsi dagokion ikonoa egoera-barran" "Gailuko argazkiak eta multimedia-edukia atzitzeko baimena eman nahi diozu <b&gt%1$s</b> aplikazioari?" diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml index a26cc48f2..f630b17ea 100644 --- a/res/values-fa/strings.xml +++ b/res/values-fa/strings.xml @@ -128,7 +128,7 @@ "بیشترین مجوزها" "بیشترین تعداد دسترسی" "اخیر" - "مرتب‌سازی براساس مصرف برنامه" + "مرتب‌سازی براساس استفاده برنامه" "مرتب‌سازی براساس زمان" "، " "بازخوانی" @@ -210,7 +210,7 @@ %s ثانیه "یادآوری‌های مجوز" - "%s از مکانتان استفاده می‌کند" + "%s به موقعیت مکانی شما در پس‌زمینه دسترسی دارد" "این برنامه همیشه می‌تواند به مکانتان دسترسی داشته باشد. برای تغییر دادن، ضربه بزنید." "تنها هنگام استفاده از برنامه" "هیچ مجوزی اعطا نشده است" @@ -280,6 +280,10 @@ "هیچ‌کدام" "(پیش‌فرض سیستم)" "برنامه‌ای موجود نیست" + + + + "دسترسی ویژه برنامه" "دسترسی ویژه برنامه" "دسترسی ویژه برنامه وجود ندارد" @@ -297,9 +301,9 @@ "رد کردن" "تنظیمات پیشرفته" "تنظیمات پیشرفته" - "نمایش استفاده از برنامه سیستم" + "نمایش استفادهٔ برنامه سیستم" "نمایش استفاده برنامه سیستم از مجوزها در نوار وضعیت، داشبورد، و جاهای دیگر" - "استفاده از برجسته کردن برای دنبال کردن" + "برجسته کردن استفاده برای موارد زیر" "نمایش تشخیص راه‌انداز دستیار" "نمایش نماد مربوطه در نوار وضعیت وقتی از میکروفون برای فعال کردن دستیار صوتی استفاده می‌شود" "‏به <b>%1$s<b> اجازه داده شود به عکس‌ها و رسانه‌های موجود در دستگاهتان دسترسی پیدا کند؟" diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml index b74a8b465..fb20db1c7 100644 --- a/res/values-fi/strings.xml +++ b/res/values-fi/strings.xml @@ -172,11 +172,11 @@ "Tämän käyttöoikeuden viimeisen käyttökerran tietoja ei ole tällä hetkellä saatavilla" "Näytä kaikki käyttöoikeudet: %1$s" "Näytä kaikki sovellukset, joilla on tämä käyttöoikeus" - "Sovellukset, joilla on tämä käyttöoikeus, voivat %1$s" + "Sovellukset, joilla on tämä käyttöoikeus, voivat %1$s." "Sovelluksilla, joilla on tämä käyttöoikeus, on pääsy liikuntatietoihisi, kuten kävelyyn, pyöräilyyn, ajamiseen, ja askelmääriin." "Sovelluksilla, joilla on tämä käyttöoikeus, on pääsy kalenteriisi." "Sovelluksilla, joilla on tämä käyttöoikeus, on puhelulokin luku- ja kirjoitusoikeus." - "Sovellukset, joilla on tämä käyttöoikeus, voivat ottaa kuvia ja kuvata videota" + "Sovellukset, joilla on tämä käyttöoikeus, voivat ottaa kuvia ja kuvata videota." "Sovelluksilla, joilla on tämä käyttöoikeus, on pääsy yhteystietoihisi." "Sovellukset, joilla on tämä käyttöoikeus, voivat käyttää laitteen sijaintia." "Sovellukset, joilla on tämä käyttöoikeus, voivat tallentaa ääntä." @@ -210,7 +210,7 @@ 1 sekunti "Käyttölupamuistutukset" - "%s on käyttänyt sijaintiasi" + "%s sai sijaintitietosi taustalla" "Tämä sovellus voi aina käyttää sijaintiasi. Muuta napauttamalla." "Vain, kun sovellusta käytetään" "Käyttöoikeuksia ei ole myönnetty" @@ -280,6 +280,10 @@ "Ei mitään" "(Järjestelmän oletusarvo)" "Ei sovelluksia" + + + + "sovellusten erikoiskäyttö" "Sovellusten erikoiskäyttö" "Ei sovellusten erikoiskäyttöä" diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml index 9950a8ebb..adb70cc19 100644 --- a/res/values-fr-rCA/strings.xml +++ b/res/values-fr-rCA/strings.xml @@ -101,7 +101,7 @@ "Les 24 dernières heures" "La dernière heure" "Les 15 dernières minutes" - "Au cours de la dernière minute" + "Dernière minute" "Aucune autoris. d\'utilisation" "L\'accès le plus récent en tout temps" "Accès le plus récent au cours des 7 derniers jours" @@ -190,7 +190,7 @@ "Refusée/aucune tentative d\'accès" "Autorisées" "Toujours autorisées" - "Autorisée seulement durant l\'utilisation" + "Autorisées seulement durant l\'utilisation" "Refusées" "Afficher les détails d\'utilisation" @@ -210,7 +210,7 @@ %s secondes "Rappels d\'autorisation" - "%s utilise l\'accès à votre position" + "L\'application %s a accédé à votre position en arrière-plan" "Cette application peut toujours accéder à votre position. Touchez l\'écran pour modifier cela." "Uniquement lorsque l\'application est en cours d\'utilisation" "Aucune autorisation accordée" @@ -280,6 +280,8 @@ "Aucune" "(Valeurs par défaut du système)" "Aucune application" + "Sélectionnée" + "Sélectionnée – %1$s" "accès spécial pour applications" "Accès spécial pour applis" "Aucun accès spécial pour applis" @@ -299,7 +301,7 @@ "Paramètres avancés" "Afficher l\'usage des applications système" "Afficher l\'utilisation des autorisations par les applications système dans la barre d\'état, le tableau de bord et ailleurs" - "Mettre en avant l\'usage pour les éléments suivants" + "Mettre en avant l\'utilisation pour les éléments suivants" "Afficher la détection des déclencheurs de l\'Assistant" "Afficher l\'icône dans la barre d\'état lorsque le microphone est utilisé pour activer l\'assistant vocal" "Autoriser « %1$s » à accéder aux photos et aux médias de votre appareil?" diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index 55fcd621c..fcd548945 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -59,7 +59,7 @@ "Aucune application" "Paramètres de localisation" "Les services de localisation pour cet appareil sont fournis via %1$s. Vous pouvez modifier l\'accès aux données de localisation dans les paramètres de localisation." - "Si vous refusez cette autorisation, il est possible que cela affecte certaines fonctionnalités de base de votre appareil." + "Si vous refusez cette autorisation, certaines fonctionnalités de base de votre appareil risquent de ne plus fonctionner correctement." "Activé conformément aux règles" "Accès en arrière-plan désactivé conformément au règlement" "Accès en arrière-plan activé conformément au règlement" @@ -180,8 +180,8 @@ "Les applications disposant de cette autorisation peuvent accéder à vos contacts" "Les applications disposant de cette autorisation peuvent accéder à la position de cet appareil" "Les applications disposant de cette autorisation peuvent enregistrer des fichiers audio" - "Les applications disposant de cette autorisation permettent de passer des appels téléphoniques et de gérer ceux-ci" - "Les applications disposant de cette autorisation peuvent accéder aux données des capteurs relatives à vos signes vitaux" + "Les applications disposant de cette autorisation permettent de passer des appels téléphoniques et de les gérer" + "Les applications disposant de cette autorisation peuvent accéder aux données des capteurs corporels" "Les applications disposant de cette autorisation peuvent envoyer et lire des SMS" "Les applications disposant de cette autorisation peuvent accéder aux photos, fichiers multimédias et autres fichiers sur votre appareil" "Dernier accès : %1$s" @@ -191,7 +191,7 @@ "Autorisées" "Toujours autorisées" "Autorisées seulement pendant l\'utilisation" - "Non authorisées" + "Non autorisées" "Afficher l\'utilisation détaillée" %s jour @@ -210,7 +210,7 @@ %s secondes "Rappels relatifs aux autorisations" - "L\'application %s utilise votre position" + "%s a accès à votre position en arrière-plan" "Cette application peut accéder en permanence à votre position. Appuyez dessus pour modifier cette autorisation." "Seulement quand l\'application est en cours d\'utilisation" "Aucune autorisation accordée" @@ -229,7 +229,7 @@ "Peut accéder aux SMS et au journal d\'appels" "Navigateur par défaut" "Navigateur" - "Applications vous permettant d\'accéder à Internet et d\'afficher des liens sur lesquels appuyer" + "Applications qui vous permettent d\'accéder à Internet et d\'afficher des liens sur lesquels appuyer" "Définir %1$s comme votre navigateur par défaut ?" "Aucune autorisation nécessaire" "Appli de téléphone par défaut" @@ -247,7 +247,7 @@ "Applications qui vous permettent d\'enregistrer vos informations médicales et de les rendre accessibles aux services de secours d\'urgence, de recevoir des alertes en cas d\'événements météorologiques violents ou d\'alerter d\'autres personnes lorsque vous avez besoin d\'aide" "Définir %1$s comme votre application par défaut pour les urgences ?" "Aucune autorisation nécessaire" - "Appli écran accueil par défaut" + "Appli écran d\'accueil par défaut" "Appli sur l\'écran d\'accueil" "Applications, souvent appelées lanceurs d\'applications, qui remplacent l\'écran d\'accueil de votre appareil Android, et vous permettent d\'accéder au contenu de l\'appareil et à ses fonctionnalités" "Définir %1$s comme votre application d\'écran d\'accueil par défaut ?" @@ -258,8 +258,8 @@ "Définir %1$s comme votre application par défaut pour la redirection des appels ?" "Aucune autorisation nécessaire" "Appli numéro de l\'appelant et spam par défaut" - "Appli numéro appelant et spam" - "Applications qui vous permettent d\'identifier les appels entrants, de bloquer le spam et les appels automatiques, de mettre en liste noire les numéros indésirables et plus encore" + "Appli numéro de l\'appelant et spam" + "Applications qui vous permettent d\'identifier les appels entrants, de bloquer le spam et les appels automatiques, de mettre sur liste noire les numéros indésirables et plus encore" "Définir %1$s comme votre application par défaut pour l\'affichage du numéro de l\'appelant et du spam ?" "Aucune autorisation nécessaire" "Appli par défaut actuelle" @@ -280,6 +280,10 @@ "Aucune" "(Application système par défaut)" "Aucune application" + + + + "accès spécifique des applications" "Accès spécifique des applis" "Aucun accès spécif. des applis" @@ -301,6 +305,6 @@ "Afficher l\'utilisation des autorisations par les applications système dans la barre d\'état, le tableau de bord et ailleurs" "Mettre en avant l\'utilisation des applications suivantes" "Afficher la détection de l\'activation de l\'Assistant" - "Afficher l\'icône dans la barre d\'état lorsque le micro est utilisé pour activer l\'assistance vocale" + "Afficher une icône dans la barre d\'état lorsque le micro est utilisé pour activer l\'assistance vocale" "Permettre à <b>%1$s</b> d\'accéder aux photos et contenus multimédias sur votre appareil ?" diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml index ac0ff1f69..d6b949fb6 100644 --- a/res/values-gl/strings.xml +++ b/res/values-gl/strings.xml @@ -124,7 +124,7 @@ "Ver todo no panel de control" "Filtrar por" "Filtrar por permisos" - "Filtrar por nome" + "Filtrar por hora" "Máis permisos" "Máis accesos" "Accesos recentes" @@ -210,7 +210,7 @@ 1 segundo "Recordatorios de permisos" - "A aplicación %s estivo utilizando a túa localización" + "A aplicación %s accedeu á túa localización en segundo plano" "Esta aplicación pode acceder sempre á túa localización. Toca para cambiar esta opción." "Só cando se estea utilizando a aplicación" "Non se concederon permisos" @@ -268,7 +268,7 @@ "aplicacións predeterminadas" "De acordo" "Config. privacidade" - "Aplicacións que utilizan o seguinte: %s" + "Aplicacións que usan: %s" ", " " e " "Configuración" @@ -280,6 +280,10 @@ "Ningunha" "(Opción predeterminada do sistema)" "Non hai ningunha aplicación" + + + + "acceso especial das aplicacións" "Acceso especial das aplicacións" "Sen acceso especial das apps" diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml index 6c48607a0..24b7b45c8 100644 --- a/res/values-gu/strings.xml +++ b/res/values-gu/strings.xml @@ -210,7 +210,7 @@ %s સેકંડ "મંજૂરીના રિમાઇન્ડર" - "%s તમારા સ્થાનનો ઉપયોગ કરી રહી છે" + "%sએ બૅકગ્રાઉન્ડમાં તમારું સ્થાન ઍક્સેસ કર્યુ છે" "આ ઍપ હંમેશાં તમારા સ્થાનને ઍક્સેસ કરી શકે છે. ફેરફાર કરવા માટે ટૅપ કરો." "માત્ર ઍપ ઉપયોગમાં હોય ત્યારે જ" "કોઈ પરવાનગીઓની મંજૂરી નથી" @@ -280,6 +280,10 @@ "કોઈ નહીં" "(સિસ્ટમ ડિફૉલ્ટ)" "કોઈ ઍપ નથી" + + + + "વિશેષ ઍપનો ઍક્સેસ" "વિશેષ ઍપનો ઍક્સેસ" "કોઈ વિશેષ ઍપનો ઍક્સેસ નથી" diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml index 1737fe667..e290e0f36 100644 --- a/res/values-hi/strings.xml +++ b/res/values-hi/strings.xml @@ -210,7 +210,7 @@ %s सेकंड "अनुमति रिमाइंडर" - "%s आपकी जगह की जानकारी का इस्तेमाल कर रहा है" + "%s अब बैकग्राउंड में आपकी जगह की जानकारी एक्सेस कर सकता है" "यह ऐप्लिकेशन हमेशा आपकी जगह की जानकारी एक्सेस कर सकता है. बदलने के लिए टैप करें." "सिर्फ़ ऐप्लिकेशन इस्तेमाल में होने के दौरान" "कोई अनुमति नहीं मिली है" @@ -229,7 +229,7 @@ "मैसेज, कॉल लॉग का एक्सेस पाएं" "डिफ़ॉल्ट ब्राउज़र ऐप्लिकेशन" "ब्राउज़र ऐप्लिकेशन" - "ऐसे ऐप्लिकेशन जो आपको इंटरनेट का एक्सेस देते हैं और टैप करने के लिए डिस्प्ले लिंक देते हैं" + "ऐसे ऐप्लिकेशन जो आपको इंटरनेट का एक्सेस देते हैं और टैप करने के लिए डिसप्ले लिंक देते हैं" "%1$s को अपने डिफ़ॉल्ट ब्राउज़र ऐप्लिकेशन के तौर पर सेट करें?" "अनुमति की ज़रूरत नहीं है" "डिफ़ॉल्ट फ़ोन ऐप्लिकेशन" @@ -280,6 +280,10 @@ "कोई नहीं" "(सिस्टम डिफ़ॉल्ट)" "कोई ऐप्लिकेशन नहीं" + + + + "ऐप्लिकेशन को खास अनुमति" "ऐप्लिकेशन को खास अनुमति" "ऐप्लिकेशन को खास अनुमति नहीं" diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml index 7f35a97cc..a37028ea7 100644 --- a/res/values-hr/strings.xml +++ b/res/values-hr/strings.xml @@ -217,7 +217,7 @@ %s sekundi "Podsjetnici za dopuštenja" - "Aplikacija %s koristi vašu lokaciju" + "Aplikacija %s pristupa vašoj lokaciji u pozadini" "Ova aplikacija može uvijek pristupiti vašoj lokaciji. Dodirnite za promjenu." "Samo dok je aplikacija u upotrebi" "Nije odobreno nijedno dopuštenje" @@ -264,9 +264,9 @@ "Aplikacije koje vam omogućuju prosljeđivanje poziva na neki drugi telefonski broj" "Želite li postaviti aplikaciju %1$s kao zadanu aplikaciju za preusmjeravanje poziva?" "Nije potrebno nijedno dopuštenje" - "Zadana ap. za ID pozivatelja/neželjene pozive" + "ID poziv. i neželj. pozivi" "Apl. za ID pozivatelja/spam" - "Aplikacije koje vam omogućuju identifikaciju dolaznih poziva, blokiranje neželjenih i automatiziranih poziva, izradu popisa nedopuštenih brojeva i tako dalje" + "Aplikacije koje vam omogućuju identifikaciju dolaznih poziva, blokiranje neželjenih i automatiziranih poziva, izradu popisa nedopuštenih brojeva i drugo" "Želite li postaviti aplikaciju %1$s kao svoju zadanu aplikaciju za ID pozivatelja i neželjene pozive?" "Nije potrebno nijedno dopuštenje" "Trenutačna zadana" @@ -287,6 +287,8 @@ "Nijedna" "(Zadana postavka sustava)" "Nema aplikacija" + "Odabrano" + "Odabrano – %1$s" "poseban pristup za aplikacije" "Poseban pristup aplikaciji" "Bez poseb. pristupa aplikaciji" @@ -305,7 +307,7 @@ "Napredne postavke" "Napredne postavke" "Prikaz upotrebe aplikacije sustava" - "Prikaz upotrebe dopuštenja za aplikaciju sustava na traci statusa, nadzornoj ploči i drugdje" + "Prikazuje upotrebu dopuštenja za aplikaciju sustava na traci statusa, nadzornoj ploči i drugdje" "Isticanje upotrebe za sljedeće" "Prikaz otkrivanja okidača Asistenta" "Prikazuje ikonu na traci statusa kada se za aktiviranje glasovne pomoći upotrebljava mikrofon" diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml index 4ed284e65..2165278f0 100644 --- a/res/values-hu/strings.xml +++ b/res/values-hu/strings.xml @@ -210,7 +210,7 @@ 1 másodperc "Engedélyekre vonatkozó emlékeztetők" - "A(z) %s az Ön tartózkodási helyét használja" + "A(z) %s hozzáfér az Ön helyadataihoz a háttérben" "Ez az alkalmazás bármikor hozzáférhet az Ön tartózkodási helyéhez. A módosításhoz koppintson." "Csak az alkalmazás használata közben" "Nincs megadott engedély" @@ -280,6 +280,10 @@ "Nincs" "(Alapértelmezett)" "Nincs alkalmazás" + + + + "különleges alkalmazás-hozzáférés" "Különleges alkalmazás-hozzáférés" "Nincs különleges hozzáférés" diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml index 6e304a554..24369355f 100644 --- a/res/values-hy/strings.xml +++ b/res/values-hy/strings.xml @@ -210,7 +210,7 @@ %s վայրկյան "Հիշեցումներ թույլտվությունների մասին" - %s» հավելվածն օգտագործում է ձեր տեղադրության մասին տվյալները" + "%s հավելվածը հետագծում է ձեր գտնվելու վայրը ֆոնային ռեժիմում" "Այս հավելվածին միշտ հասանելի են ձեր տեղադրության մասին տվյալները: Փոխելու համար հպեք:" "Միայն երբ հավելվածն օգտագործվում է" "Թույլտվությունները տրված չեն" @@ -280,6 +280,10 @@ "Չկա" "(Համակարգի կանխադրված հավելված)" "Հավելվածներ չկան" + + + + "հատուկ հասանելիություն հավելվածների համար" "Հատուկ հասանելիություն" "Հատուկ հասանելիություն չկա" diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml index 0de7b1b87..ca3d21f26 100644 --- a/res/values-in/strings.xml +++ b/res/values-in/strings.xml @@ -38,7 +38,7 @@ "tidak ada yang dinonaktifkan" "Izinkan" "Izinkan sepanjang waktu" - "Izinkan hanya sewaktu aplikasi digunakan" + "Izinkan hanya saat aplikasi digunakan" "Izinkan sepanjang waktu" "Aplikasi" "Izin aplikasi" @@ -73,7 +73,7 @@ "Izinkan sepanjang waktu" - "Izinkan sewaktu apl digunakan" + "Izinkan saat apl digunakan" "Tolak" "Memuat…" "Semua izin" @@ -141,7 +141,7 @@ "Akses: %1$s kali. Terakhir digunakan %2$s yang lalu." "Izinkan" "Izinkan sepanjang waktu" - "Izinkan hanya sewaktu aplikasi digunakan" + "Izinkan hanya saat aplikasi digunakan" "Tolak" "Izin %1$s" "Akses %1$s untuk aplikasi ini" @@ -187,7 +187,7 @@ "Akses terakhir: %1$s" "Saat ini ditolak / Akses terakhir: %1$s" "Tidak pernah mengakses" - "Ditolak / Tidak pernah diakses" + "Ditolak / Tidak pernah mengakses" "Diizinkan" "Diizinkan sepanjang waktu" "Hanya diizinkan saat digunakan" @@ -210,7 +210,7 @@ 1 detik "Pengingat izin" - "%s sedang menggunakan lokasi Anda" + "%s mendapatkan lokasi Anda di latar belakang" "Aplikasi ini selalu dapat mengakses lokasi Anda. Tap untuk mengubah." "Hanya saat aplikasi sedang digunakan" "Tidak ada izin" @@ -247,7 +247,7 @@ "Aplikasi yang memungkinkan Anda mencatat info medis dan membuatnya dapat diakses oleh petugas tanggap darurat, mendapatkan pemberitahuan tentang peristiwa cuaca dan bencana yang parah, dan memberi tahu orang lain saat Anda memerlukan bantuan" "Tetapkan %1$s sebagai aplikasi darurat default Anda?" "Tidak ada izin yang diperlukan" - "Aplikasi beranda default" + "Aplikasi layar utama default" "Aplikasi layar utama" "Aplikasi, biasa disebut peluncur, yang menggantikan Layar utama di perangkat Android dan memberi Anda akses ke konten dan fitur di perangkat Anda" "Tetapkan %1$s sebagai aplikasi beranda default Anda?" @@ -259,7 +259,7 @@ "Tidak ada izin yang diperlukan" "Aplikasi nomor penelepon & spam default" "Apl nomor penelepon & spam" - "Aplikasi yang memungkinkan Anda mengidentifikasi panggilan masuk, memblokir spam dan robocall, memasukkan nomor yang tidak diinginkan ke daftar hitam, dan sebagainya" + "Aplikasi yang memungkinkan Anda mengidentifikasi panggilan masuk, memblokir spam dan robocall, memasukkan nomor ke daftar nomor tak diinginkan, dan sebagainya" "Tetapkan %1$s sebagai aplikasi nomor penelepon & spam default Anda?" "Tidak ada izin yang diperlukan" "Default saat ini" @@ -280,6 +280,8 @@ "Tidak Ada" "(Default sistem)" "Tidak ada aplikasi" + "Dipilih" + "Dipilih - %1$s" "akses aplikasi khusus" "Akses aplikasi khusus" "Tidak ada akses apl khusus" diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml index 3bd361c0f..f0d17101e 100644 --- a/res/values-is/strings.xml +++ b/res/values-is/strings.xml @@ -210,7 +210,7 @@ %s sekúndur "Áminningar um heimild" - "%s hefur verið að nota staðsetningu þína" + "%s er með staðsetningu þína í bakgrunni" "Þetta forrit hefur alltaf aðgang að staðsetningu þinni. Ýttu til að breyta." "Aðeins þegar forritið er í notkun" "Engar heimildir leyfðar" @@ -280,6 +280,8 @@ "Ekkert" "(Sjálfgildi kerfis)" "Engin forrit" + "Valið" + "Valið – %1$s" "sérstakur forritaaðgangur" "Sérstakur forritaaðgangur" "Enginn sérstakur forritaaðgangur" diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml index 72beccf95..5539f4242 100644 --- a/res/values-it/strings.xml +++ b/res/values-it/strings.xml @@ -175,7 +175,7 @@ "Le app con questa autorizzazione possono %1$s" "Le app con questa autorizzazione possono accedere alla tua attività fisica, come camminate, giri in bici, tragitti in auto, numero di passi e altro" "Le app con questa autorizzazione possono accedere al tuo calendario" - "Le app con questa autorizzazione possono leggere e scrivere il registro chiamate del telefono" + "Le app con questa autorizzazione possono leggere e modificare il registro chiamate del telefono" "Le app con questa autorizzazione possono scattare foto e registrare video" "Le app con questa autorizzazione possono accedere ai tuoi contatti" "Le app con questa autorizzazione possono accedere alla posizione di questo dispositivo" @@ -189,7 +189,7 @@ "Accesso mai eseguito" "Rifiutata/Accesso mai effettuato" "Consentite" - "Accesso sempre consentito" + "Sempre consentite" "Consentite solo durante l\'uso" "Rifiutate" "Vedi dati dettagliati sull\'utilizzo" @@ -210,7 +210,7 @@ 1 secondo "Promemoria autorizzazione" - "L\'app %s sta usando la tua posizione" + "%s ha recuperato la tua posizione in background" "Questa app può accedere sempre alla tua posizione. Tocca per modificare." "Solo mentre l\'app è in uso" "Nessuna autorizzazione consentita" @@ -280,6 +280,8 @@ "Nessuna" "(Predefinita)" "Nessuna app" + "Selezionata" + "Selezionata - %1$s" "accesso speciale alle app" "Accesso speciale alle app" "Nessun accesso speciale ad app" diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml index 99cd265c0..92e744a95 100644 --- a/res/values-iw/strings.xml +++ b/res/values-iw/strings.xml @@ -224,7 +224,7 @@ שנייה אחת "תזכורות להרשאות" - "נעשה שימוש במיקום שלך על ידי %s" + "האפליקציה %s קיבלה גישה ברקע למיקום שלך" "האפליקציה הזו יכולה תמיד לגשת למיקום שלך. יש להקיש כדי לשנות הגדרה זו." "רק בזמן שהאפליקציה בשימוש" "לא ניתנו הרשאות" @@ -294,6 +294,10 @@ "ללא" "(ברירת מחדל של המערכת)" "אין אפליקציות" + + + + "גישה מיוחדת של אפליקציה" "גישה מיוחדת לאפליקציה" "אין גישה מיוחדת לאפליקציה" diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml index 456ace00d..1c889bd26 100644 --- a/res/values-ja/strings.xml +++ b/res/values-ja/strings.xml @@ -59,7 +59,7 @@ "アプリがありません" "位置情報の設定" "%1$sはこのデバイスの位置情報サービスのプロバイダです。位置情報へのアクセスは位置情報の設定から変更できます。" - "この権限を許可しないと、お使いのデバイスの基本的な機能が意図されたとおりに動作しなくなる可能性があります。" + "この権限を許可しない場合、デバイスの基本機能が正しく動作しなくなることがあります。" "ポリシーにより適用" "バックグラウンドでのアクセスはポリシーによって無効です" "バックグラウンドでのアクセスはポリシーによって有効です" @@ -210,7 +210,7 @@ 1秒 "権限のリマインダー" - "%s は位置情報を使用しています" + "%s がバックグラウンドで位置情報を取得しました" "このアプリは常に位置情報にアクセスできます。設定を変更するにはタップしてください。" "アプリが使用中の場合のみ" "許可されている権限はありません" @@ -280,6 +280,10 @@ "なし" "(システムのデフォルト)" "アプリなし" + + + + "特別なアプリアクセス" "特別なアプリアクセス" "特別なアプリアクセスなし" diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml index bd6e74d11..8308876d7 100644 --- a/res/values-ka/strings.xml +++ b/res/values-ka/strings.xml @@ -210,7 +210,7 @@ 1 წამი "შეხსენებები ნებართვის შესახებ" - "%s იყენებს თქვენს მდებარეობას" + "%s-მა მიიღო თქვენი მდებარეობა ფონურ რეჟიმში" "ამ აპს ყოველთვის შეუძლია თქვენს მდებარეობაზე წვდომა. შეეხეთ შესაცვლელად." "მხოლოდ აპის გამოყენებისას" "დაშვებული ნებართვები არ არის" @@ -280,6 +280,8 @@ "არცერთი" "(სისტემის ნაგულისხმევი)" "აპები არ არის" + "არჩეული" + "არჩეული - %1$s" "აპების სპეციალური წვდომა" "აპების სპეციალური წვდომა" "აპების სპეციალური წვდომა არაა" diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml index aa5e3bbef..fb36079b5 100644 --- a/res/values-kk/strings.xml +++ b/res/values-kk/strings.xml @@ -38,7 +38,7 @@ "ешқандай рұқсат өшірілмеді" "Рұқсат беру" "Әрқашан рұқсат беру" - "Қолданбаны пайдалану кезінде ғана рұқсат ету" + "Қолданбаны пайдалану кезінде ғана рұқсат беру" "Біржола рұқсат ету" "Қолданбалар" "Қолданба рұқсаттары" @@ -57,7 +57,7 @@ "Жүйені көрсету" "Жүйені жасыру" "Қолданбалар жоқ" - "Орынды анықтау параметрлері" + "Орналасу параметрлері" "%1$s – осы құрылғыға орынды анықтау қызметтерін көрсететін қолданба. Орынды пайдалану мүмкіндігін орынды анықтау параметрлерінде өзгертуге болады." "Бұл рұқсатты бермесеңіз, құрылғының негізгі функциялары енді көзделгендей жұмыс істемеуі мүмкін." "Саясат арқылы қолданылған" @@ -141,7 +141,7 @@ "Кіру рұқсаты сұралды: %1$s рет. Соңғы рет %2$s бұрын пайдаланылған." "Рұқсат беру" "Әрдайым рұқсат беру" - "Қолданбаны пайдалану кезінде ғана рұқсат ету" + "Қолданбаны пайдалану кезінде ғана рұқсат беру" "Тыйым салу" "%1$s рұқсаты" "%1$s: осы қолданбаны пайдалану рұқсаты" @@ -183,7 +183,7 @@ "Бұл рұқсатқа ие қолданбалар телефон қоңырауларын шала және басқара алады." "Бұл рұқсатқа ие қолданбалар тіршілік белгілері туралы датчик деректерін пайдалана алады." "Бұл рұқсатқа ие қолданбалар SMS хабарларын жібере және көре алады." - "Рұқсатқа ие қолданбалар құрылғыдағы фотосуреттерді, медиамазмұндарды және файлдарды пайдалана алады." + "Рұқсатқа ие қолданбалар құрылғыдағы фотосуреттерді, медиафайлдарды және басқа да файлдарды пайдалана алады." "Соңғы рет пайдаланған уақыты: %1$s" "Әзірге тыйым салынған/Соңғы пайдаланылған уақыты: %1$s" "Ешқашан пайдаланбады" @@ -210,7 +210,7 @@ 1 секунд "Рұқсат туралы еске салғыштар" - "%s қолданбасы геодерегіңізді пайдаланып келді" + "%s сіздің орналасқан жеріңізді фондық режимде анықтады." "Бұл қолданба геодерегіңізді кез келген уақытта пайдалана алады. Өзгерту үшін түртіңіз." "Қолданба пайдаланып жатқанда ғана" "Ешқандай рұқсат берілмеді" @@ -280,6 +280,10 @@ "Жоқ" "(жүйенің әдепкі қолданбасы)" "Қолданбалар жоқ" + + + + "арнайы қолданба рұқсаты" "Арнайы кіру" "Арнайы кіру мүмкіндігі жоқ" diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml index 5ac86d26a..7e9ec90d2 100644 --- a/res/values-km/strings.xml +++ b/res/values-km/strings.xml @@ -172,7 +172,7 @@ "បច្ចុប្បន្ន ទិន្នន័យអំពីការចូលប្រើប្រាស់ចុងក្រោយមិនមានសម្រាប់ការ​អនុញ្ញាត​នេះទេ" "មើល​ការអនុញ្ញាតឱ្យទៅ %1$s ទាំងអស់" "មើលកម្មវិធី​ទាំងអស់​ដែលមាន​ការអនុញ្ញាត​នេះ" - "កម្មវិធី​ដែលមាន​ការអនុញ្ញាតនេះ​អាច %1$s" + "កម្មវិធី​ដែលមាន​ការអនុញ្ញាតនេះ​អាច%1$s" "កម្មវិធី​ដែលមាន​ការអនុញ្ញាត​នេះ​អាច​ចូលប្រើ​សកម្មភាពរាងកាយ ដូចជាការដើរ ការជិះកង់ ការបើកបរ ចំនួនជំហាន និងអ្វីៗច្រើនទៀត" "កម្មវិធី​ដែល​មាន​ការអនុញ្ញាតនេះ​អាចចូល​ប្រើ​ប្រតិទិនរបស់អ្នក" "កម្មវិធី​ដែលមាន​ការអនុញ្ញាត​នេះ​អាចអាន និងសរសេរកំណត់ហេតុហៅទូរសព្ទ​" @@ -210,7 +210,7 @@ 1 វិនាទី "ការរំលឹក​អំពី​ការអនុញ្ញាត" - "%s បានប្រើប្រាស់​ទីតាំង​របស់អ្នក" + "%s បានទទួល​ទីតាំង​របស់អ្នក​នៅផ្ទៃខាងក្រោយ" "កម្មវិធី​នេះ​អាច​ចូលប្រើប្រាស់​ទីតាំង​របស់អ្នក​បានជា​និច្ច។ សូម​ចុច​ដើម្បី​ប្ដូរ។" "ពេល​កំពុង​ប្រើប្រាស់​កម្មវិធីតែ​ប៉ុណ្ណោះ" "មិន​បាន​ផ្ដល់ការអនុញ្ញាតទេ" @@ -280,6 +280,10 @@ "គ្មាន" "(លំនាំដើមប្រព័ន្ធ)" "គ្មានកម្មវិធី​ទេ​" + + + + "ការចូលប្រើកម្មវិធីពិសេស" "ការចូលប្រើកម្មវិធីពិសេស" "គ្មានការចូលប្រើ​កម្មវិធី​ពិសេសទេ" diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml index 1a8385a2c..b785d4aac 100644 --- a/res/values-kn/strings.xml +++ b/res/values-kn/strings.xml @@ -210,7 +210,7 @@ %s ಸೆಕೆಂಡುಗಳು "ಅನುಮತಿ ಜ್ಞಾಪನೆಗಳು" - "%s ನಿಮ್ಮ ಸ್ಥಳವನ್ನು ಬಳಸುತ್ತಿದೆ" + "%s ನಿಮ್ಮ ಸ್ಥಳವನ್ನು ಹಿನ್ನಲೆಯಲ್ಲಿ ಪಡೆದುಕೊಂಡಿದೆ" "ಈ ಆ್ಯಪ್‌ ಯಾವಾಗಲೂ ನಿಮ್ಮ ಸ್ಥಳವನ್ನು ಪ್ರವೇಶಿಸಬಹುದು. ಬದಲಾಯಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ." "ಆ್ಯಪ್ ಬಳಕೆಯಲ್ಲಿದ್ದಾಗ ಮಾತ್ರ" "ಯಾವುದೇ ಅನುಮತಿಗಳನ್ನು ಅನುಮತಿಸಲಾಗಿಲ್ಲ" @@ -280,6 +280,10 @@ "ಯಾವುದೂ ಬೇಡ" "(ಸಿಸ್ಟಂ ಡಿಫಾಲ್ಟ್)" "ಯಾವುದೇ ಆ್ಯಪ್‌ಗಳು ಇಲ್ಲ" + + + + "ವಿಶೇಷ ಆ್ಯಪ್ ಪ್ರವೇಶ" "ಆ್ಯಪ್‌ಗೆ ವಿಶೇಷ ಪ್ರವೇಶ" "ಆ್ಯಪ್‌ಗೆ ವಿಶೇಷ ಪ್ರವೇಶವಿಲ್ಲ" diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml index 4c834f290..fcbc622db 100644 --- a/res/values-ko/strings.xml +++ b/res/values-ko/strings.xml @@ -123,12 +123,12 @@ "필터링 기준: %1$s" "대시보드에서 모두 보기" "필터링 기준" - "권한별로 필터링" + "권한으로 필터링" "시간으로 필터링" "사용된 권한 수" "액세스 횟수" "최근" - "앱 사용량순 정렬" + "앱 사용 시간순 정렬" "시간순 정렬" ", " "새로고침" @@ -210,7 +210,7 @@ 1초 "권한 알림" - "%s에서 내 위치를 사용함" + "%s에서 백그라운드에서 내 위치에 액세스함" "이 앱에서 내 위치에 항상 액세스할 수 있습니다. 변경하려면 탭하세요." "앱 사용 중에만" "허용된 권한 없음" @@ -239,7 +239,7 @@ "통화 기록 액세스 및 SMS 전송 권한" "기본 SMS 앱" "SMS 앱" - "내 전화번호를 사용하여 짧은 SMS, 사진, 동영상 등을 보내고 받을 수 있는 앱" + "내 전화번호를 사용하여 SMS, 사진, 동영상 등을 보내고 받을 수 있는 앱" "%1$s 앱을 기본 SMS 앱으로 설정하시겠습니까?" "연락처, SMS, 전화에 액세스" "기본 긴급 앱" @@ -280,6 +280,10 @@ "없음" "(시스템 기본값)" "앱 없음" + + + + "특수 앱 액세스 권한" "특수 앱 액세스 권한" "특수 앱 액세스 권한 없음" diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml index b1b187259..a6d65c8b3 100644 --- a/res/values-ky/strings.xml +++ b/res/values-ky/strings.xml @@ -120,7 +120,7 @@ 1 колдонмо "Баарын Куралдар тактасында көрүү" - "Төмөнкү боюнча чыпкаланды: %1$s" + "Чыпка: %1$s" "Баарын Куралдар тактасында көрүү" "Төмөнкү боюнча чыпкалоо:" "Уруксаттар боюнча чыпкалоо" @@ -186,12 +186,12 @@ "Мындай уруксаты бар колдонмолор түзмөгүңүздөгү сүрөттөрүңүздү, медиафайлдарыңызды жана башка файлдарыңызды көрө алышат" "Акыркы жолу качан колдонулду: %1$s" "Учурда четке кагылган / Акыркы колдонулушу: %1$s" - "Эч качан колдонулган эмес" - "Четке кагылган / Эч качан колдонулган эмес" + "Колдонула элек" + "Четке кагылган / Колдонулган эмес" "Уруксат берилген" "Бардык учурда уруксат берилди" "Колдонулган кезде гана уруксат" - "Четке кагылды" + "Четке кагылган" "Бардык уруксаттардын колдонулушун көрүү" %s күн @@ -210,13 +210,13 @@ 1 секунд "Уруксат жөнүндө эстеткичтер" - "%s кайда жүргөнүңүз тууралуу маалыматты колдонуп жатат" + "%s жайгашкан жериңизди фондон алды" "Бул колдонмо кайда жүргөнүңүздү ар дайым билип турат. Аны өзгөртүү үчүн таптап коюңуз." "Колдонмо пайдаланылып жаткан учурда гана" "Колдонмого уруксаттар берилген жок" "Колдонмого бардык уруксаттар берилди" "Бир да колдонмого уруксат берилген жок" - "Бардык колдонмолорго уруксат берилди" + "Бардык колдонмолорго уруксат берилген" "Жөндөөлөр" "%s кызматынын түзмөгүңүзгө кирүүгө толук мүмкүнчүлүгү бар" "%s атайын мүмкүнчүлүктөр колдонмолорунун түзмөгүңүзгө кирүүгө толук мүмкүнчүлүгү бар" @@ -280,6 +280,10 @@ "Жок" "(Демейки тутум)" "Бир да колдонмо жок" + + + + "колдонмонун атайын уруксаты" "Колдонмонун атайын уруксаты" "Колднмнун атайын уруксаты жок" @@ -302,5 +306,5 @@ "Тандалган колдонмолорду көрсөтүү" "Үн жардамчысынын иштегенин чагылдырган сүрөтчөнү көрсөтүү" "Үн жардамчысын иштетүү үчүн микрофон колдонулганда, абал тилкесинде сүрөтчө көрүнөт" - "<b>%1$s</b> колдонмосуна түзмөгүңүздөгү сүрөттөрдү жана мультимедиа файлдарын пайдаланууга уруксат берилсинби?" + "<b>%1$s</b> колдонмосу үчүн түзмөгүңүздөгү сүрөттөр менен мультимедиа файлдарын иштетесизби?" diff --git a/res/values-lo/strings.xml b/res/values-lo/strings.xml index f4e97336b..2e1741fba 100644 --- a/res/values-lo/strings.xml +++ b/res/values-lo/strings.xml @@ -210,7 +210,7 @@ 1 ວິນາທີ "ການແຈ້ງເຕືອນການອະນຸຍາດ" - "%s ໄດ້ໃຊ້ສະຖານທີ່ຂອງທ່ານແລ້ວ" + "%s ໄດ້ຂໍ້ມູນສະຖານທີ່ຂອງທ່ານໃນພື້ນຫຼັງແລ້ວ" "ແອັບນີ້ສາມາດເຂົ້າເຖິງສະຖານທີ່ຂອງທ່ານໄດ້ຕະຫຼອດເວລາ. ແຕະເພື່ອປ່ຽນແປງ." "ສະເພາະເມື່ອມີການໃຊ້ແອັບ" "ບໍ່ມີສິດທີ່ອະນຸຍາດ" @@ -280,6 +280,8 @@ "ບໍ່ມີ" "(ຄ່າເລີ່ມຕົ້ນຂອງລະບົບ)" "ບໍ່ມີແອັບ" + "ເລືອກແລ້ວ" + "ເລືອກແລ້ວ - %1$s" "ສິດການເຂົ້າເຖິງແອັບພິເສດ" "ສິດການເຂົ້າເຖິງແອັບພິເສດ" "ບໍ່ມີສິດການເຂົ້າເຖິງແອັບພິເສດ" diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml index b04a5455a..5aa533fa4 100644 --- a/res/values-lt/strings.xml +++ b/res/values-lt/strings.xml @@ -224,7 +224,7 @@ %s sekundžių "Leidimų priminimai" - "Programa „%s“ naudojo jūsų vietovę" + "Programa „%s“ gavo vietovės duomenis fone" "Ši programa visada gali pasiekti jūsų vietovę. Palieskite, kad pakeistumėte." "Tik tada, kai programa naudojama" "Nesuteikta jokių leidimų" @@ -294,6 +294,10 @@ "Nėra" "(Sistemos numatytoji programa)" "Nėra programų" + + + + "speciali prieiga prie programų" "Speciali prieiga prie programų" "Nėra spec. prieig. prie progr." diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml index 3d0b6f4cf..4af10849e 100644 --- a/res/values-lv/strings.xml +++ b/res/values-lv/strings.xml @@ -217,7 +217,7 @@ %s sekundes "Atgādinājumi par atļauju" - "Lietotne %s jau kādu laiku izmanto jūsu atrašanās vietu" + "Lietotne %s ieguva jūsu atrašanās vietas informāciju fonā" "Šī lietotne jebkurā laikā var piekļūt jūsu atrašanās vietai. Pieskarieties, lai mainītu šo iestatījumu." "Tikai lietotnes izmantošanas laikā" "Nav piešķirta neviena atļauja" @@ -287,6 +287,10 @@ "Nav" "(Sistēmas noklusējums)" "Nav lietotņu" + + + + "Īpaša lietotņu piekļuve" "Īpaša piekļuve lietotnēm" "Nav īpašas piekļuves lietotnēm" diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml index 9f8034876..3a5917a1c 100644 --- a/res/values-mk/strings.xml +++ b/res/values-mk/strings.xml @@ -210,7 +210,7 @@ %s секунди "Потсетници за дозволата" - "%s ја користи вашата локација" + "%s ја има вашата локација во заднина" "Апликацијава секогаш може да пристапува до вашата локација. Допрете за да го промените тоа." "Само додека се користи апликацијата" "Нема овозможени дозволи" @@ -280,6 +280,8 @@ "Нема" "(Стандардно за системот)" "Нема апликации" + "Избрана" + "Избрана - %1$s" "посебен пристап за апликации" "Посебен пристап за апликации" "Нема посебен пристап за аплик." @@ -301,6 +303,6 @@ "Прикажувај го користењето дозволи од системските апликации во статусната лента, контролната табла и на други места" "Нагласи го користењето за следново" "Прикажувај го откривањето за активирање на „Помошникот“" - "Прикажувај икона во статусната лента кога микрофонот се користи за активирање „Гласовна помош“" + "Прикажувај икона во статусната лента кога микрофонот се користи за активирање на гласовниот помошник" "Да се дозволи <b>%1$s</b> да пристапува до фотографии и аудиовизуелни содржини на уредот?" diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml index cccea9711..7178b818d 100644 --- a/res/values-ml/strings.xml +++ b/res/values-ml/strings.xml @@ -210,7 +210,7 @@ ഒരു സെക്കൻഡ് "അനുമതിയ്ക്കുള്ള റിമൈൻഡറുകൾ" - "%sഎന്ന ആപ്പ് നിങ്ങളുടെ ലൊക്കേഷൻ ഉപയോഗിക്കുന്നു" + "%s-ന് നിങ്ങളുടെ ലൊക്കേഷൻ പശ്ചാത്തലത്തിൽ ലഭിച്ചു" "ഈ ആപ്പിന് എപ്പോഴും നിങ്ങളുടെ ലൊക്കേഷൻ ആക്‌സസ് ചെയ്യാനാവും. മാറ്റാൻ ടാപ്പ് ചെയ്യുക." "ആപ്പ് ഉപയോഗത്തിലുള്ളപ്പോൾ മാത്രം" "അനുമതികളൊന്നും നൽകിയിട്ടില്ല" @@ -280,6 +280,10 @@ "ഒന്നുമില്ല" "(സിസ്‌റ്റം ഡിഫോൾട്ട്)" "ആപ്പുകൾ ഒന്നുമില്ല" + + + + "പ്രത്യേക ആപ്പ് ആക്‌സസ്" "പ്രത്യേക ആപ്പ് ആക്‌സസ്" "പ്രത്യേക ആപ്പ് ആക്‌സസില്ല" diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml index 04948aa18..3d15b05de 100644 --- a/res/values-mn/strings.xml +++ b/res/values-mn/strings.xml @@ -173,7 +173,7 @@ "%1$s-н бүх зөвшөөрлийг харах" "Энэ зөвшөөрөлтэй бүх аппыг харах" "Энэ зөвшөөрөлтэй аппууд %1$s боломжтой" - "Энэ зөвшөөрөлтэй аппууд таны алхалт, дугуй уналт, жолоодлого, алхмын тоо болон бусад зэрэг биеийн дасгал хөдөлгөөнд хандах боломжтой" + "Энэ зөвшөөрөлтэй аппууд таны алхалт, дугуй унах, жолоодлого, алхмын тоо болон бусад биеийн дасгал хөдөлгөөнд хандах боломжтой" "Энэ зөвшөөрөлтэй аппууд таны хуанлид хандах боломжтой" "Энэ зөвшөөрөлтэй аппууд утасны дуудлагын жагсаалтыг унших болон бичих боломжтой" "Энэ зөвшөөрөлтэй аппууд зураг авах болон видео хийх боломжтой" @@ -210,7 +210,7 @@ 1 секунд "Зөвшөөрлийн сануулагч" - "%s таны байршлыг ашигласаар байна" + "%s таны арын байршлыг авсан" "Энэ апп таны байршилд тогтмол хандах боломжтой байна. Өөрчлөхийн тулд товшино уу." "Зөвхөн аппыг ашиглаж байх үед" "Ямар ч зөвшөөрөл алга" @@ -280,6 +280,10 @@ "Тохируулсан апп алга" "(Системийн өгөгдмөл)" "Апп алга" + + + + "аппын тусгай хандалт" "Аппын тусгай хандалт" "Аппын тусгай хандалт алга" diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml index 3413d140f..b8ded38ed 100644 --- a/res/values-mr/strings.xml +++ b/res/values-mr/strings.xml @@ -101,7 +101,7 @@ "गेल्या २४ तासात" "शेवटचा एक तास" "शेवटची १५ मिनिटे" - "अंतिम एक मिनिट" + "शेवटचा एक मिनिट" "वापराची परवानगी नाही" "कोणत्याही वेळी सर्वात अलीकडील अ‍ॅक्सेस" "मागील सात दिवसांतील सर्वात अलीकडील अ‍ॅक्सेस" @@ -210,7 +210,7 @@ एक सेकंद "परवानगी रिमाइंडर" - "%s तुमचे स्थान वापरत आहे" + "%s ने बॅकग्राउंडमध्ये तुमचे स्थान मिळवले" "हे अ‍ॅप नेहमी तुमचे स्थान अॅक्सेस करू शकते. बदलण्यासाठी टॅप करा." "फक्त अ‍ॅप वापरत असताना" "कोणत्याही परवानगीची अनुमती नाही" @@ -280,6 +280,10 @@ "काहीही नाही" "(सिस्टम डीफॉल्ट)" "अॅप्स नाहीत" + + + + "विशेष अ‍ॅप अॅक्सेस" "विशेष अॅप अॅक्सेस" "कोणताही विशेष अॅप अॅक्सेस नाही" diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml index b5b8d822f..0af1aadc0 100644 --- a/res/values-ms/strings.xml +++ b/res/values-ms/strings.xml @@ -210,7 +210,7 @@ 1 saat "Peringatan kebenaran" - "%s telah menggunakan lokasi anda" + "%s mendapat lokasi anda di latar belakang" "Apl ini boleh mengakses lokasi anda pada setiap masa. Ketik untuk menukar." "Hanya semasa apl sedang digunakan" "Tiada kebenaran dibenarkan" @@ -280,6 +280,10 @@ "Tiada" "(Lalai sistem)" "Tiada apl" + + + + "akses apl khas" "Akses apl khas" "Tiada akses apl khas" diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml index cdae09600..93524fce6 100644 --- a/res/values-my/strings.xml +++ b/res/values-my/strings.xml @@ -210,7 +210,7 @@ ၁ စက္ကန့် "ခွင့်ပြုချက် သတိပေးမှုများ" - "%s က သင်၏တည်နေရာကို အသုံးပြုနေပါသည်" + "%s သည် နောက်ခံတွင် သင့်တည်နေရာကို ရရှိထားသည်" "ဤအက်ပ်က သင်၏တည်နေရာကို အမြဲဝင်ကြည့်နိုင်ပါသည်။ ပြောင်းရန် တို့ပါ။" "အက်ပ်ကို အသုံးပြုနေစဉ်သာ" "ခွင့်ပြုချက်များ ပေးမထားပါ" @@ -280,6 +280,8 @@ "မရှိ" "(စနစ်မူလ)" "အက်ပ် မရှိပါ" + "ရွေးထားသည်" + "ရွေးထားသည် - %1$s" "အထူးအက်ပ်များ ဝင်သုံးခွင့်" "အထူးအက်ပ်များ သုံးခွင့်ရှိသည်" "အထူးအက်ပ်များ သုံးခွင့်မရှိပါ" @@ -298,9 +300,9 @@ "အဆင့်မြင့် ဆက်တင်များ" "အဆင့်မြင့် ဆက်တင်များ" "စက်စနစ်အက်ပ် အသုံးပြုမှု ပြပါ" - "စက်စနစ်အက်ပ်၏ ခွင့်ပြုချက်များ အသုံးပြုမှုကို အခြေအနေဘား၊ ဒက်ရှ်ဘုတ်နှင့် အခြားနေရာများတွင် ပြသသည်" + "စက်စနစ်အက်ပ်၏ ခွင့်ပြုချက်များ အသုံးပြုမှုကို အခြေအနေဘား၊ ဒက်ရှ်ဘုတ်နှင့် အခြားနေရာများတွင် ပြပါ" "အောက်ပါအတွက် အသုံးပြုမှုကို အထူးအသားပေးခြင်း" "Assistant စတင်မှုဆိုင်ရာ သိရှိစနစ်ကို ပြပါ" - "\'အသံ အကူအညီ\' စတင်ရန် မိုက်ခရိုဖုန်းအသုံးပြုသည့်အခါ သင်္ကေတကို အခြေအနေဘားတွင် ပြပါသည်" + "အသံအကူအညီ စတင်ရန် မိုက်ခရိုဖုန်းအသုံးပြုသည့်အခါ သင်္ကေတကို အခြေအနေဘားတွင် ပြပါ" "<b>%1$s</b> အား သင့်စက်ပေါ်ရှိ ဓာတ်ပုံနှင့် မီဒီယာဖိုင်များ ဝင်သုံးခွင့်ပေးလိုပါသလား။" diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml index 06dce543c..7ed9eee61 100644 --- a/res/values-nb/strings.xml +++ b/res/values-nb/strings.xml @@ -124,7 +124,7 @@ "Se alt i oversikten" "Filtrér etter" "Filtrér etter tillatelser" - "Filtrer etter tid" + "Filtrér etter tid" "Flest tillatelser" "Mest brukt" "Nylig" @@ -210,7 +210,7 @@ 1 sekund "Påminnelser om tillatelser" - "%s har brukt posisjonen din" + "%s fikk posisjonen din i bakgrunnen" "Denne appen har alltid tilgang til posisjonen din. Trykk for å endre." "Bare mens appen er i bruk" "Ingen tillatelser er gitt" @@ -242,10 +242,10 @@ "Apper som lar deg bruke telefonnummeret til å sende og motta korte tekstmeldinger, bilder, videoer med mer" "Vil du angi %1$s som standardapp for SMS?" "Får tilgang til kontakter, SMS, telefon" - "Standardapp for nødsituasjoner" + "Standardapp for nødssituasjoner" "Nødapp" "Apper som lar deg registrere den medisinske informasjonen din og gjøre den tilgjengelig til utrykningspersonell, motta varsler om ekstremvær og katastrofer, og varsle andre når du trenger hjelp" - "Vil du angi %1$s som standardapp for nødsituasjoner?" + "Vil du angi %1$s som standardapp for nødssituasjoner?" "Ingen tillatelser er nødvendige" "Standard startsideapp" "Startsideapp" @@ -280,6 +280,10 @@ "Ingen" "(Systemstandard)" "Ingen apper" + + + + "spesiell apptilgang" "Spesiell apptilgang" "Ingen spesiell apptilgang" @@ -300,7 +304,7 @@ "Vis systemappenes bruk" "Vis systemappenes bruk av tillatelser i statusfelt, oversikt og andre steder" "Fremhev bruk for følgende" - "Vis registrering utløst av Assistent" + "Vis aktivering av Assistent" "Vis ikon i statusfeltet når mikrofonen brukes til å aktivere taleassistent" "Vil du gi <b>%1$s</b> tilgang til bilder og medier på enheten din?" diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml index 800653b9e..56402cbeb 100644 --- a/res/values-ne/strings.xml +++ b/res/values-ne/strings.xml @@ -210,7 +210,7 @@ १ सेकेन्ड "अनुमतिसम्बन्धी रिमाइन्डरहरू" - "%s ले तपाईंको स्थान प्रयोग गरिरहेको छ" + "%s ले पृष्ठभूमिमा तपाईंको स्थानमाथिको पहुँच प्राप्त गर्‍यो" "यो अनुप्रयोगले सधैँ तपाईंको स्थान प्रयोग गर्न सक्छ। बदल्न ट्याप गर्नुहोस्‌।" "अनुप्रयोग प्रयोगमा भएको बेला मात्र" "कुनै पनि अनुमति छैन" @@ -280,6 +280,10 @@ "कुनै पनि होइन" "(प्रणालीको पूर्वनिर्धारित अनुप्रयोग)" "कुनै पनि अनुप्रयोग छैन" + + + + "अनुप्रयोगसम्बन्धी विशेष पहुँच" "अनुप्रयोगसम्बन्धी विशेष पहुँच" "एपसम्बन्धी कुनै विशेष पहुँच छैन" diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml index 18ad8b8ea..4a9d364f7 100644 --- a/res/values-nl/strings.xml +++ b/res/values-nl/strings.xml @@ -95,7 +95,7 @@ "Dashboard" "Laatste keer geopend: %1$s\nLaatste keer geopend terwijl de app werd gebruikt" "Laatste keer geopend: %1$s\nLaatst geopend op de achtergrond" - "Elk recht" + "Minstens 1 recht" "Altijd" "Afgelopen 7 dagen" "Afgelopen 24 uur" @@ -148,7 +148,7 @@ "%1$s heeft %3$s geleden toegang tot je %2$s gehad" "%1$s heeft %2$s geleden toegang tot je fysieke activiteit gehad" "%1$s heeft %2$s geleden toegang tot je agenda gehad" - "%1$s heeft %2$s geleden toegang tot je gesprekkenlijsten gehad" + "%1$s heeft %2$s geleden toegang tot je gesprekslijsten gehad" "%1$s heeft %2$s geleden toegang tot je camera gehad" "%1$s heeft %2$s geleden toegang tot je contacten gehad" "%1$s heeft %2$s geleden toegang tot je locatie gehad" @@ -160,7 +160,7 @@ "%1$s heeft geen toegang tot je %2$s gehad" "%1$s heeft geen toegang tot je fysieke activiteit gehad" "%1$s heeft geen toegang tot je agenda gehad" - "%1$s heeft geen toegang tot je gesprekkenlijsten gehad" + "%1$s heeft geen toegang tot je gesprekslijsten gehad" "%1$s heeft geen toegang tot je camera gehad" "%1$s heeft geen toegang tot je contacten gehad" "%1$s heeft geen toegang tot je locatie gehad" @@ -175,7 +175,7 @@ "Apps met dit recht kunnen %1$s" "Apps met dit recht hebben toegang tot je fysieke activiteit, zoals wandelen, fietsen, autorijden, aantal stappen en meer" "Apps met dit recht hebben toegang tot je agenda" - "Apps met dit recht kunnen de gesprekkenlijst van je telefoon lezen en erin schrijven" + "Apps met dit recht kunnen de gesprekslijst van je telefoon lezen en erin schrijven" "Apps met dit recht kunnen foto\'s maken en video opnemen" "Apps met dit recht hebben toegang tot je contacten" "Apps met dit recht hebben toegang tot de locatie van dit apparaat" @@ -210,7 +210,7 @@ 1 seconde "Herinneringen voor rechten" - "%s maakt gebruik van je locatie" + "%s had toegang tot je locatie op de achtergrond" "Deze app heeft altijd toegang tot je locatie. Tik om dit te wijzigen." "Alleen terwijl de app wordt gebruikt" "Geen rechten verleend" @@ -226,7 +226,7 @@ "App voor assistentie" "Assistentie-apps kunnen je helpen op basis van de informatie op het scherm dat je bekijkt. Bepaalde apps ondersteunen launcher- en spraakinvoerservices voor geïntegreerde ondersteuning." "%1$s instellen als standaard-app voor assistentie?" - "Krijgt toegang tot sms en gesprekkenlijst" + "Krijgt toegang tot sms en gesprekslijst" "Standaard browser-app" "Browser-app" "Apps die toegang tot internet geven en de links weergeven waarop je hebt getikt" @@ -236,7 +236,7 @@ "Telefoon-app" "Apps waarmee je kunt bellen en gebeld kunt worden op je apparaat" "%1$s instellen als standaard telefoon-app?" - "Krijgt toegang tot gesprekkenlijst en kan sms\'jes verzenden" + "Krijgt toegang tot gesprekslijst en kan sms\'jes verzenden" "Standaard sms-app" "Sms-app" "Apps waarmee je met je telefoonnummer onder andere sms\'jes, foto\'s en video\'s kunt verzenden en ontvangen" @@ -280,6 +280,8 @@ "Geen" "(Systeemstandaard)" "Geen apps" + "Geselecteerd" + "Geselecteerd: %1$s" "speciale app-toegang" "Speciale app-toegang" "Geen speciale app-toegang" diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml index 2ad44033b..7fd0a57b0 100644 --- a/res/values-or/strings.xml +++ b/res/values-or/strings.xml @@ -94,7 +94,7 @@ "ଅଜଣା" "ଡ୍ୟାସ୍‍‍ବୋର୍ଡ" "ଶେଷ ଆକ୍ସେସ୍: ଆପ୍ ବ୍ୟବହାର କରିବା ସମୟରେ %1$s\nରେ ଶେଷଥର ଆକ୍ସେସ୍ କରାଯାଇଥିଲା" - "ଶେଷ ଆକ୍ସେସ୍: ପୃଷ୍ଠଭୂମିରେ %1$s\nରେ ଶେଷଥର ଆକ୍ସେସ୍ କରାଯାଇଥିଲା" + "ଗତ ଆକ୍ସେସ୍:%1$s\n ପୃଷ୍ଠଭୂମିରେ ଗତଥର ଆକ୍ସେସ୍ କରାଯାଇଥିଲା" "ଯେକୌଣସି ଅନୁମତି" "ଯେକୌଣସି ସମୟରେ" "ଗତ 7 ଦିନ" @@ -128,7 +128,7 @@ "ଅଧିକ ଅନୁମତିଗୁଡିକ" "ସର୍ବାଧିକ ଆକ୍ସେସ୍‍ଗୁଡିକ" "ସମ୍ପ୍ରତି" - "ବ୍ୟବହାର ଅନୁସାରେ ଆପ୍‌କୁ ସଜାନ୍ତୁ" + "ଆପ୍‌ ବ୍ୟବହାର ଅନୁସାରେ ସଜାନ୍ତୁ" "ସମୟ ଅନୁସାରେ ସଜାନ୍ତୁ" ", " "ରିଫ୍ରେଶ୍ କରନ୍ତୁ" @@ -189,7 +189,7 @@ "କେବେବି ଆକ୍ସେସ୍ ହୋଇନାହିଁ" "ପ୍ରତ୍ୟାଖ୍ୟାନ କରାଯାଇଛି / କେବେବି ଆକ୍ସେସ୍ ହୋଇନାହିଁ" "ଅନୁମୋଦିତ" - "ସର୍ବଦା ଅନୁମତି ଦିଅନ୍ତୁ" + "ସର୍ବଦା ଅନୁମତି ଦିଆଯାଇଥିବା ଆପ୍ସ" "କେବଳ ବ୍ୟବହାର ପାଇଁ ଅନୁମତି ଦିଆଯାଇଛି" "ପ୍ରତ୍ୟାଖ୍ୟାନ କରାଗଲା" "ବିସ୍ତାରିତ ବ୍ୟବହାର ଦେଖନ୍ତୁ" @@ -210,7 +210,7 @@ 1 ସେକେଣ୍ଡ "ଅନୁମତି ରିମାଇଣ୍ଡର୍" - "%s ଆପଣଙ୍କ ଲୋକେସନ୍ ବ୍ୟବହାର କରୁଛନ୍ତି" + "%s ପୃଷ୍ଠପଟରେ ଆପଣଙ୍କ ଲୋକେସନ୍ ପାଇଛି" "ଏହି ଆପ୍ ସବୁବେଳେ ଆପଣଙ୍କ ଲୋକେସନ୍ ଆକ୍ସେସ୍ କରିପାରିବ। ବଦଳାଇବା ପାଇଁ ଟାପ୍ କରନ୍ତୁ" "କେବଳ ଆପ୍‍ ବ୍ୟବହାରରେ ରହିଥିବା ବେଳେ" "କୌଣସି ଅନୁମତି ଦିଆଯାଇ ନାହିଁ" @@ -259,7 +259,7 @@ "କୌଣସି ଅନୁମତି ଆବଶ୍ୟକ ନାହିଁ" "ଡିଫଲ୍ଟ କଲର୍ ID & ସ୍ପାମ୍ ଆପ୍" "କଲର୍ ID & ସ୍ପାମ୍ ଆପ୍" - "ଆପ୍ସ ଯାହା ଆପଣଙ୍କୁ ଇନ୍‌କମିଂ କଲ୍, ବ୍ଲକ୍ ସ୍ପାମ୍ ଏବଂ ରୋବୋକଲ୍, ବ୍ଲାକ୍‌ଲିଷ୍ଟ ଅଦରକାରୀ ସଂଖ୍ୟା, ଏବଂ ଅନେକ କିଛି ଚିହ୍ନଟ କରିବା ପାଇଁ ଅନୁମତି ଦିଏ" + "ଆପ୍ସ ଯାହା ଆପଣଙ୍କୁ ଇନ୍‌କମିଂ କଲ୍, ବ୍ଲକ୍ ସ୍ପାମ୍ ଏବଂ ରୋବୋକଲ୍, ବ୍ଲାକ୍‌ଲିଷ୍ଟରେ ଥିବା ଅନାବଶ୍ୟକ ନମ୍ବର ଏବଂ ଅନେକ କିଛି ଚିହ୍ନଟ କରିବା ପାଇଁ ଅନୁମତି ଦିଏ" "%1$sକୁ ଆପଣଙ୍କର ଡିଫଲ୍ଟ କଲର୍ ଆଇଡି & ସ୍ପାମ୍ ଆପ୍ ଭାବ୍ ସେଟ୍ କରିବେ କି?" "କୌଣସି ଅନୁମତି ଆବଶ୍ୟକ ନାହିଁ" "ସମ୍ପ୍ରତ୍ତି ଡିଫଲ୍ଟ" @@ -275,11 +275,15 @@ "ଡିଫଲ୍ଟ ଆପ୍ସ" "କୌଣସି ଡିଫଲ୍ଟ ଆପ୍ସ ନାହିଁ" "ଅଧିକ ଡିଫଲ୍ଟଗୁଡ଼ିକ" - "ଲିଙ୍କ୍‌ଗୁଡ଼ିକ ଖୋଲୁଛି" + "ଓପନିଂ ଲିଙ୍କ୍" "କାର୍ଯ୍ୟ ପାଇଁ ଡିଫଲ୍ଟ ଅଛି" "କିଛି ଆପ୍‌ ସେଟ୍‌ କରାଯାଇନାହିଁ" "(ସିଷ୍ଟମ୍ ଡିଫଲ୍ଟ)" "କୌଣସି ଆପ୍‌ ନାହିଁ" + + + + "ବିଶେଷ ଆପ୍‌ ଆକ୍ସେସ୍‌" "ସ୍ୱତନ୍ତ୍ର ଆପ୍‌ ଆକ୍ସେସ୍‌" "କୌଣସି ସ୍ଵତନ୍ତ୍ର ଆପ୍‍ ଆକ୍ସେସ୍‍ ନାହିଁ" diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml index 1cf19dab7..d3a59ff95 100644 --- a/res/values-pa/strings.xml +++ b/res/values-pa/strings.xml @@ -210,7 +210,7 @@ %s ਸਕਿੰਟ "ਇਜਾਜ਼ਤਾਂ ਦੀਆਂ ਯਾਦ-ਸੂਚਨਾਵਾਂ" - "%s ਨੇ ਤੁਹਾਡੀ ਟਿਕਾਣਾ ਜਾਣਕਾਰੀ ਵਰਤੀ ਹੈ" + "%s ਨੂੰ ਬੈਕਗ੍ਰਾਉਂਡ ਵਿੱਚ ਤੁਹਾਡੇ ਟਿਕਾਣੇ ਦੀ ਜਾਣਕਾਰੀ ਮਿਲੀ" "ਇਹ ਐਪ ਹਮੇਸ਼ਾਂ ਤੁਹਾਡੀ ਟਿਕਾਣਾ ਜਾਣਕਾਰੀ \'ਤੇ ਪਹੁੰਚ ਕਰ ਸਕਦੀ ਹੈ। ਬਦਲਣ ਲਈ ਟੈਪ ਕਰੋ।" "ਸਿਰਫ਼ ਐਪ ਵਰਤੇ ਜਾਣ ਵੇਲੇ" "ਕੋਈ ਇਜਾਜ਼ਤਾਂ ਨਹੀਂ ਦਿੱਤੀਆਂ ਗਈਆਂ ਹਨ" @@ -280,6 +280,10 @@ "ਕੋਈ ਨਹੀਂ" "(ਸਿਸਟਮ ਪੂਰਵ-ਨਿਰਧਾਰਤ)" "ਕੋਈ ਐਪਾਂ ਨਹੀਂ" + + + + "ਖਾਸ ਐਪ ਪਹੁੰਚ" "ਵਿਸ਼ੇਸ਼ ਐਪ ਪਹੁੰਚ" "ਕੋਈ ਵਿਸ਼ੇਸ਼ ਐਪ ਪਹੁੰਚ ਨਹੀਂ" diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml index e1c80024c..d79443795 100644 --- a/res/values-pl/strings.xml +++ b/res/values-pl/strings.xml @@ -132,7 +132,7 @@ "Najwięcej uprawnień" "Najczęściej używane" "Ostatnio" - "Sortuj wg aplikacji" + "Sortuj według aplikacji" "Sortuj według godziny" ", " "Odśwież" @@ -180,24 +180,24 @@ "Wyświetl wszystkie aplikacje z tymi uprawnieniami" "Aplikacje z tymi uprawnieniami mają %1$s" "Aplikacje z tymi uprawnieniami mają dostęp do danych o Twojej aktywności fizycznej takiej jak spacery, jazda na rowerze, jazda samochodem, liczba kroków i inne" - "Aplikacje z tymi uprawnieniami mają dostęp do kalendarza" + "Aplikacje z tymi uprawnieniami mają dostęp do kalendarza" "Aplikacje z tymi uprawnieniami mogą odczytywać i zapisywać rejestr połączeń telefonicznych" "Aplikacje z tymi uprawnieniami mogą robić zdjęcia i nagrywać filmy" - "Aplikacje z tymi uprawnieniami mają dostęp do kontaktów" - "Aplikacje z tymi uprawnieniami mają dostęp do lokalizacji tego urządzenia" + "Aplikacje z tymi uprawnieniami mają dostęp do kontaktów" + "Aplikacje z tymi uprawnieniami mają dostęp do lokalizacji tego urządzenia" "Aplikacje z tymi uprawnieniami mogą nagrywać dźwięk" - "Aplikacje z tymi uprawnieniami mogą nawiązywać połączenia telefoniczne i zarządzać nimi." + "Aplikacje z tymi uprawnieniami mogą nawiązywać połączenia telefoniczne i nimi zarządzać" "Aplikacje z tymi uprawnieniami mają dostęp do danych z czujnika podstawowych funkcji życiowych" - "Aplikacje z tymi uprawnieniami mogą wysyłać i wyświetlać SMS-y" + "Aplikacje z tymi uprawnieniami mogą wysyłać i wyświetlać SMS-y" "Aplikacje z tymi uprawnieniami mają dostęp do zdjęć, multimediów i plików na urządzeniu" "Ostatnie użycie: %1$s" "Aktualnie odmowa / ostatni dostęp: %1$s" "Nigdy nie użyto" "Odmowa / nigdy nie użyto" - "Dozwolone" - "Ciągły dostęp" - "Zgoda na dostęp tylko podczas używania" - "Niedozwolone" + "Mają dostęp" + "Mają ciągły dostęp" + "Mają dostęp tylko podczas używania" + "Nie mają dostępu" "Zobacz szczegółowe informacje o użyciu" %s dni @@ -224,7 +224,7 @@ 1 sekunda "Przypomnienia o uprawnieniach" - "Aplikacja %s używa Twojej lokalizacji" + "Aplikacja %s uzyskała dostęp do Twojej lokalizacji w tle" "Ta aplikacja może zawsze uzyskać dostęp do Twojej lokalizacji. Kliknij, by to zmienić." "Tylko podczas używania aplikacji" "Nie przyznano żadnych uprawnień" @@ -251,9 +251,9 @@ "Aplikacje umożliwiające nawiązywanie i odbieranie połączeń telefonicznych na urządzeniu" "Czy aplikacja %1$s ma być domyślną aplikacją do obsługi telefonu?" "Otrzymuje dostęp do rejestru połączeń i wysyłania SMS-ów" - "Domyślna aplikacja – SMS-y" + "Domyślna aplikacja SMS" "Aplikacja do SMS-ów" - "Aplikacje umożliwiające użycie Twojego numeru telefonu do wysyłania i odbierania SMS-ów, zdjęć, filmów i innych danych." + "Aplikacje umożliwiające użycie Twojego numeru telefonu do wysyłania i odbierania SMS-ów, zdjęć, filmów i innych danych" "Czy aplikacja %1$s ma być domyślną aplikacją do SMS-ów?" "Otrzymuje dostęp do kontaktów, SMS-ów, telefonu" "Domyślna aplikacja alarmowa" @@ -263,7 +263,7 @@ "Nie potrzebuje uprawnień" "Domyślna ap. ekranu głównego" "Aplikacja ekranu głównego" - "Aplikacje, często nazywane programami uruchamiającymi, które zastępują ekrany główne na urządzeniu z Androidem i zapewniają dostęp do zawartości oraz funkcji urządzenia." + "Aplikacje często nazywane programami uruchamiającymi, które zastępują ekrany główne na urządzeniu z Androidem i zapewniają dostęp do zawartości oraz funkcji urządzenia" "Czy aplikacja %1$s ma być domyślną aplikacją ekranu głównego?" "Nie potrzebuje uprawnień" "Domyślna aplikacja do przekierowywania połączeń" @@ -271,9 +271,9 @@ "Aplikacje umożliwiające przekazywanie połączeń pod inny numer telefonu" "Czy aplikacja %1$s ma być domyślną aplikacją do przekierowywania połączeń?" "Nie potrzebuje uprawnień" - "Domyślna aplikacja do identyfikacji rozmówców i spamu" + "Domyślna aplik. ident. rozmówców i spam" "Aplikacja do identyfikacji rozmówcy i spamu" - "Aplikacje umożliwiające m.in. identyfikowanie połączeń przychodzących, blokowanie spamu i automatycznych wiadomości telefonicznych, dodawanie numerów do czarnej listy." + "Aplikacje umożliwiające m.in. identyfikowanie połączeń przychodzących, blokowanie spamu i automatycznych wiadomości telefonicznych, dodawanie numerów do czarnej listy" "Czy aplikacja %1$s ma być domyślną aplikacją do identyfikacji rozmówcy i spamu?" "Nie potrzebuje uprawnień" "Bieżąca aplikacja domyślna" @@ -294,9 +294,13 @@ "Brak" "(Domyślna aplikacja systemu)" "Brak aplikacji" + + + + "aplikacje ze specjalnym dostępem" "Aplikacje ze specjalnym dostępem" - "Brak specjalnego dostępu do aplikacji" + "Brak aplikacji ze specjalnym dostępem" "Brak aplikacji" "Nie obsługuje profilu do pracy" "Uwaga: Po ponownym uruchomieniu urządzenia z ustawioną blokadą ekranu ta aplikacja będzie mogła uruchomić się dopiero wtedy, gdy odblokujesz urządzenie." @@ -311,9 +315,9 @@ "Odmów" "Ustawienia zaawansowane" "Ustawienia zaawansowane" - "Pokaż informacje o użyciu dotyczące aplikacji systemowej" - "Pokaż na pasku stanu, w panelu i innych miejscach korzystanie z uprawnień przez aplikację systemową" - "Wyróżnij te informacje o użyciu" + "Pokaż wykorzystanie uprawnień przez aplikacje systemowe" + "Pokaż na pasku stanu, w panelu i innych miejscach korzystanie z uprawnień przez aplikacje systemowe" + "Wyróżnij informacje o użyciu uprawnień przez" "Pokaż wykrywanie wyzwalacza Asystenta" "Pokaż ikonę na pasku stanu, gdy używany jest mikrofon do uruchomienia asystenta głosowego" "Zezwolić aplikacji <b>%1$s</b> na dostęp do zdjęć i multimediów na urządzeniu?" diff --git a/res/values-pt-rBR/strings.xml b/res/values-pt-rBR/strings.xml index a190a3c59..509dac561 100644 --- a/res/values-pt-rBR/strings.xml +++ b/res/values-pt-rBR/strings.xml @@ -143,7 +143,7 @@ "Permitir o tempo todo" "Permitir durante o uso do app" "Negar" - "Permissão de %1$s" + "Acesso aos recursos de %1$s" "Permitir que este app acesse o app %1$s" "%1$s acessou %2$s%3$s" "%1$s acessou sua atividade física há %2$s" @@ -210,7 +210,7 @@ %s segundos "Lembretes de permissões" - "O app %s está usando sua localização" + "O app %s tem acesso à sua localização em segundo plano" "Este app pode acessar sua localização a qualquer momento. Toque para alterar." "Apenas enquanto o app estiver em uso" "Nenhuma permissão autorizada" @@ -280,6 +280,8 @@ "Nenhum" "(Padrão do sistema)" "Nenhum app" + "Selecionado" + "Selecionado: %1$s" "Acesso especial de app" "Acesso especial ao app" "Nenhum acesso especial ao app" @@ -300,7 +302,7 @@ "Mostrar uso de apps do sistema" "Mostrar apps do sistema que usam as permissões na barra de status, no painel e em outros lugares" "Destacar uso para os apps a seguir" - "Mostrar detecção de gatilho do Assistente" - "Mostrar ícone na barra de status quando o microfone for usado para ativar o assistente por viva-voz" + "Mostrar quando o Assistente detectar uma frase de gatilho" + "Mostrar ícone na barra de status quando o microfone for usado para ativar o assistente por voz" "Permitir que <b>%1$s</b> acesse fotos e mídia no seu dispositivo?" diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml index 776667de3..40d0fd3e2 100644 --- a/res/values-pt-rPT/strings.xml +++ b/res/values-pt-rPT/strings.xml @@ -116,12 +116,12 @@ "Utilização das autorizações nos últimos 15 minutos" "Utilização das autorizações no último minuto" - %s aplic. - 1 aplic. + %s apps + 1 app "Ver tudo no painel de controlo" "Filtrado por: %1$s" - "Ver todas no painel de controlo" + "Ver tudo no painel de controlo" "Filtrar por" "Filtrar por autorizações" "Filtrar por hora" @@ -210,7 +210,7 @@ 1 segundo "Lembretes de autorização" - "A aplicação %s tem estado a utilizar a sua localização" + "A aplicação %s obteve a sua localização em segundo plano" "Esta aplicação consegue aceder sempre à sua localização. Toque para alterar." "Apenas enquanto a aplicação está a ser utilizada" "Nenhuma autorização permitida." @@ -258,7 +258,7 @@ "Pretende definir %1$s como a aplicação de redirecionamento de chamadas predefinida?" "Não são necessárias autorizações." "Aplicação identific. chamadas e spam predef." - "Aplic. ident. chamadas e spam" + "App de ID de chamada e spam" "Aplicações que permitem identificar as chamadas recebidas, bloquear spam e chamadas automáticas, adicionar números indesejados à lista negra, etc." "Pretende definir o %1$s como a aplicação de identificação de chamadas e spam predefinida?" "Não são necessárias autorizações." @@ -280,6 +280,8 @@ "Nenhuma" "(Predefinição do sistema)" "Sem aplicações" + "Selecionada" + "Selecionada – %1$s" "acesso especial a aplicações" "Acesso especial a aplicações" "Sem acesso especial a aplic." diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml index a190a3c59..509dac561 100644 --- a/res/values-pt/strings.xml +++ b/res/values-pt/strings.xml @@ -143,7 +143,7 @@ "Permitir o tempo todo" "Permitir durante o uso do app" "Negar" - "Permissão de %1$s" + "Acesso aos recursos de %1$s" "Permitir que este app acesse o app %1$s" "%1$s acessou %2$s%3$s" "%1$s acessou sua atividade física há %2$s" @@ -210,7 +210,7 @@ %s segundos "Lembretes de permissões" - "O app %s está usando sua localização" + "O app %s tem acesso à sua localização em segundo plano" "Este app pode acessar sua localização a qualquer momento. Toque para alterar." "Apenas enquanto o app estiver em uso" "Nenhuma permissão autorizada" @@ -280,6 +280,8 @@ "Nenhum" "(Padrão do sistema)" "Nenhum app" + "Selecionado" + "Selecionado: %1$s" "Acesso especial de app" "Acesso especial ao app" "Nenhum acesso especial ao app" @@ -300,7 +302,7 @@ "Mostrar uso de apps do sistema" "Mostrar apps do sistema que usam as permissões na barra de status, no painel e em outros lugares" "Destacar uso para os apps a seguir" - "Mostrar detecção de gatilho do Assistente" - "Mostrar ícone na barra de status quando o microfone for usado para ativar o assistente por viva-voz" + "Mostrar quando o Assistente detectar uma frase de gatilho" + "Mostrar ícone na barra de status quando o microfone for usado para ativar o assistente por voz" "Permitir que <b>%1$s</b> acesse fotos e mídia no seu dispositivo?" diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml index a778cea20..73281bcd9 100644 --- a/res/values-ro/strings.xml +++ b/res/values-ro/strings.xml @@ -217,7 +217,7 @@ O secundă "Mementouri de permisiune" - "%s folosește locația dvs." + "%s v-a obținut locația în fundal" "Această aplicație poate accesa întotdeauna locația dvs. Atingeți ca să modificați." "Numai când aplicația este folosită" "Nicio permisiune" @@ -282,11 +282,15 @@ "Aplicații prestabilite" "Nicio aplicație prestabilită." "Mai multe setări prestabilite" - "Se deschid linkurile" + "Deschiderea linkurilor" "Prestabilite pentru serviciu" "Niciuna" "(Valoare prestabilită de sistem)" "Nicio aplicație" + + + + "acces special pentru aplicații" "Acces special pentru aplicații" "Niciun acces special pentru aplicații" diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index 101920d85..97d2edba3 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -59,7 +59,7 @@ "Показать системные процессы" "Скрыть системные процессы" "Нет приложений" - "Открыть настройки доступа" + "Настройки геолокации" "Приложение \"%1$s\" обеспечивает геолокацию на этом устройстве. Вы всегда можете изменить настройки доступа к данным о местоположении." "Без этого разрешения основные функции устройства могут работать неправильно." "В соответствии с правилами" @@ -181,14 +181,14 @@ "Приложения с этим разрешением могут выполнять следующие действия: %1$s" "Приложения с этим разрешением могут получить доступ к данным о вашей физической активности, например прогулках, поездках на велосипеде, количестве пройденных шагов и пр." "Приложения с этим разрешением могут получать доступ к календарю." - "Приложения с этим разрешением могут получать доступ к списку вызовов и изменять его." + "Приложения с этим разрешением могут читать список вызовов и создавать записи в нем." "Приложения с этим разрешением могут снимать фото и видео." "Приложения с этим разрешением могут получать доступ к контактам." "Приложения с этим разрешением могут получать доступ к местоположению устройства." "Приложения с этим разрешением могут записывать аудио." "Приложения с этим разрешением могут совершать звонки и управлять ими." "Приложения с этим разрешением могут получать доступ к данным датчиков о состоянии организма." - "Приложения с этим разрешением могут получать доступ к SMS и отправлять их." + "Приложения с этим разрешением могут отправлять и просматривать SMS-сообщения." "Приложения с этим разрешением могут получить доступ к фотографиям, медиа и другим файлам на вашем устройстве." "Последний раз использовано: %1$s" "Временно запрещено / Последний доступ: %1$s" @@ -224,7 +224,7 @@ %s сек. "Напоминания о разрешениях" - "Приложение \"%s\" использовало ваши геоданные" + "Приложению \"%s\" в фоновом режиме доступны геоданные" "У этого приложения есть постоянный доступ к сведениям о вашем местоположении. Нажмите, чтобы изменить настройки." "Разрешить только в активном режиме" "Разрешения не предоставлены" @@ -294,6 +294,10 @@ "Нет" "(по умолчанию)" "Приложений нет" + + + + "специальный доступ для приложений" "Спец. доступ для приложений" "Специальный доступ не настроен" diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml index 9ed00dd7c..aa9cd039b 100644 --- a/res/values-si/strings.xml +++ b/res/values-si/strings.xml @@ -210,7 +210,7 @@ තත්පර %s "අවසර සිහි කැඳවීම්" - "%s ඔබේ ස්ථානය භාවිත කරමින් සිටියි" + "%s පසුබිම තුළ ඔබේ ස්ථානය ලබා ගත්තා" "මෙම යෙදුම සැමවිටම ඔබේ ස්ථානය වෙත ප්‍රවේශ විය හැක. වෙනස් කිරීමට තට්ටු කරන්න." "යෙදුම භාවිතයේ දී පමණි" "අවසරවලට ඉඩ නොදේ" @@ -280,6 +280,8 @@ "කිසිවක් නැත" "(පද්ධතිය පෙරනිමි)" "යෙදුම් නොමැත" + "තේරිණි" + "තේරිණි - %1$s" "විශේෂ යෙදුම් ප්‍රවේශය" "විශේෂ යෙදුම් ප්‍රවේශය" "විශේෂිත යෙදුම් ප්‍රවේශයක් නැත" diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml index fea8f3dab..263e4e7c8 100644 --- a/res/values-sk/strings.xml +++ b/res/values-sk/strings.xml @@ -96,14 +96,14 @@ "Neznáme" "Hlavný panel" "Posledný prístup: %1$s\nposledný prístup pri používaní aplikácie" - "Posledný prístup: %1$s\nposledný prístup na pozadí" + "Posledný prístup: %1$s\nPosledný prístup na pozadí" "Všetky povolenia" "Kedykoľvek" "Posledných 7 dní" "Posledných 24 hodín" - "Posledná hodina" + "Posledná 1 hodina" "Posledných 15 minút" - "Posledná minúta" + "Posledná 1 minúta" "Žiadne využitie povolení" "Posledný prístup kedykoľvek" "Posledný prístup za posledných sedem dní" @@ -126,7 +126,7 @@ "Zobraziť všetko v hlavnom paneli" "Filtrované podľa: %1$s" "Zobraziť všetko v hlavnom paneli" - "Filtrovať podľa" + "Filter" "Filtrovať podľa povolení" "Filtrovať podľa času" "Najviac povolení" @@ -154,7 +154,7 @@ "Aplikácia %1$s použila povolenie %2$s pred %3$s" "Aplikácia %1$s použila fyzickú aktivitu pred %2$s" "Aplikácia %1$s použila kalendár pred %2$s" - "Aplikácia %1$s použila denníky hovorov pred %2$s" + "Aplikácia %1$s použila zoznam hovorov pred %2$s" "Aplikácia %1$s použila fotoaparát pred %2$s" "Aplikácia %1$s použila kontakty pred %2$s" "Aplikácia %1$s použila polohu pred %2$s" @@ -162,11 +162,11 @@ "Aplikácia %1$s použila telefón pred %2$s" "Aplikácia %1$s použila senzory pred %2$s" "Aplikácia %1$s použila SMS pred %2$s" - "Aplikácia %1$s použila ukladací priestor pred %2$s" + "Aplikácia %1$s použila úložisko pred %2$s" "Aplikácia %1$s nepoužila povolenie %2$s" "Aplikácia %1$s nepoužila fyzickú aktivitu" "Aplikácia %1$s nepoužila kalendár" - "Aplikácia %1$s nepoužila denníky hovorov" + "Aplikácia %1$s nepoužila zoznam hovorov" "Aplikácia %1$s nepoužila fotoaparát" "Aplikácia %1$s nepoužila kontakty" "Aplikácia %1$s nepoužila polohu" @@ -181,7 +181,7 @@ "Aplikácie s týmto povolením môžu %1$s" "Aplikácie s týmto povolením majú prístup k fyzickej aktivite, napríklad chôdzi, bicyklovaniu, šoférovaniu, počtu krokov a pod." "Aplikácie s týmto povolením majú prístup k vášmu kalendáru" - "Aplikácie s týmto povolením môžu čítať denník hovorov telefónu a zapisovať doň" + "Aplikácie s týmto povolením môžu čítať a zapisovať do zoznamu hovorov" "Aplikácie s týmto povolením môžu snímať fotky a video" "Aplikácie s týmto povolením majú prístup k vašim kontaktom" "Aplikácie s týmto povolením majú prístup k polohe tohto zariadenia" @@ -224,7 +224,7 @@ 1 s "Pripomenutia povolení" - "%s používa vašu polohu" + "Aplikácia %s získala vašu polohu na pozadí" "Táto aplikácia má neobmedzený prístup k polohe. Klepnutím to zmeníte." "Iba počas používania aplikácie" "Žiadne udelené povolenia" @@ -242,12 +242,12 @@ "Chcete %1$s nastaviť ako predvolenú asistenčnú aplikáciu?" "Získa prístup k správam SMS, denníku hovorov" "Predvolený prehliadač" - "Aplikácia na prehliadanie" + "Prehliadač" "Aplikácie, ktoré vám poskytujú prístup k internetu a zobrazujú odkazy, na ktoré môžete klepnúť" "Chcete %1$s nastaviť ako predvolený prehliadač?" "Nie sú potrebné žiadne povolenia" - "Predvolená aplikácia na telefonovanie" - "Aplikácia Telefón" + "Predvolená telefónna aplikácia" + "Telefónna aplikácia" "Aplikácie, ktoré vám v zariadení umožňujú uskutočňovať a prijímať telefonické hovory" "Chcete nastaviť %1$s ako predvolenú aplikáciu na telefonovanie?" "Získa prístup k denníku hovorov, odosielaniu správ SMS" @@ -271,10 +271,10 @@ "Aplikácie, ktoré vám umožňujú presmerovať hovory na iné telefónne číslo" "Chcete %1$s nastaviť ako predvolenú aplikáciu na presmerovanie hovorov?" "Nie sú potrebné žiadne povolenia" - "Predvolená aplikácia na identifikáciu volajúceho a spam" - "Aplikácia na identifikáciu volajúceho a spam" + "Predvolená aplikácia na identifikáciu volajúcich a spamu" + "Identifikácia volajúcich a spamu" "Aplikácia, ktorá vám umožňuje identifikovať prichádzajúce hovory, blokovať spam a robotické hovory, pridávať nechcené čísla do zoznamu zakázaných čísel a pod." - "Chcete %1$s nastaviť ako predvolenú aplikáciu na identifikáciu volajúceho a spam?" + "Chcete aplikáciu %1$s nastaviť ako predvolenú aplikáciu na identifikáciu volajúcich a spamu?" "Nie sú potrebné žiadne povolenia" "Aktuálne predvolená" "Nabudúce sa nepýtať" @@ -294,6 +294,10 @@ "Žiadna" "(Predvolená systémová)" "Žiadne aplikácie" + + + + "špeciálny prístup aplikácií" "Špeciálny prístup aplikácií" "Žiadny špeciálny prístup aplikácií" @@ -314,7 +318,7 @@ "Zobrazovať využitie systémovými aplikáciami" "Zobrazovať využitie povolení systémovými aplikáciami v stavovom riadku, hlavnom paneli a inde" "Zvýrazniť využitie týmito aplikáciami" - "Zobrazovať rozpoznávanie spúšťania Asistenta" + "Zobrazovať detekciu spustenia asistenta" "Zobrazovať v stavovom riadku ikonu, keď bude pomocou mikrofónu aktivovaný hlasový asistent" "Chcete povoliť aplikácii <b>%1$s</b> používať fotky a médiá v zariadení?" diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml index 3c040e006..705b50bd6 100644 --- a/res/values-sl/strings.xml +++ b/res/values-sl/strings.xml @@ -56,7 +56,7 @@ "Ta aplikacija je bila zasnovana za starejšo različico sistema Android. Če dovoljenje zavrnete, lahko preneha delovati, kot bi morala." "izvedba neznanega dejanja" "Dovoljene aplikacije: %1$d od %2$d" - "Prikaz sistemskih procesov" + "Prikaži sistemske procese" "Skrivanje sistemskih procesov" "Ni aplikacij" "Nastavitve lokacije" @@ -95,8 +95,8 @@ "Priprava aplikacije …" "Neznano" "Nadzorna plošča" - "Zadnji dostop: %1$s\nZadnji dostop med uporabo aplikacije" - "Zadnji dostop: %1$s\nZadnji dostop v ozadju" + "Zadnja uporaba: %1$s\nZadnja uporaba dovoljenja med uporabo aplikacije" + "Zadnja uporaba: %1$s\nZadnja uporaba v ozadju" "Katero koli dovoljenje" "Kadar koli" "Zadnjih 7 dni" @@ -105,12 +105,12 @@ "Zadnjih 15 minut" "Zadnja minuta" "Ni uporabe dovoljenj" - "Zadnji dostop kadar koli" - "Zadnji dostop v zadnjih 7 dneh" - "Zadnji dostop v zadnjih 24 urah" - "Zadnji dostop v zadnji uri" - "Zadnji dostop v zadnjih 15 minutah" - "Zadnji dostop v zadnji minuti" + "Zadnja uporaba kadar koli" + "Zadnja uporaba v zadnjih 7 dneh" + "Zadnja uporaba v zadnjih 24 urah" + "Zadnja uporaba v zadnji uri" + "Zadnja uporaba v zadnjih 15 minutah" + "Zadnja uporaba v zadnji minuti" "Uporaba dovoljenj kadar koli" "Uporaba dovoljenj v zadnjih 7 dneh" "Uporaba dovoljenj v zadnjih 24 urah" @@ -128,12 +128,12 @@ "Prikaži vse na nadzorni plošči" "Filtriraj po" "Filtriraj po dovoljenjih" - "Filtriraj glede na čas" + "Filtriraj po času" "Največ dovoljenj" "Največ dostopov" "Nedavno" "Razvrsti po uporabi aplikacije" - "Razvrsti glede na čas" + "Razvrsti po času" ", " "Osveži" @@ -175,7 +175,7 @@ "Aplikacija %1$s ni dostopala do tipal" "Aplikacija %1$s ni dostopala do sporočil SMS" "Aplikacija %1$s ni dostopala do shrambe" - "Podatki o zadnjem dostopu trenutno niso na voljo za to dovoljenje" + "Podatki o zadnji uporabi tega dovoljenja trenutno niso na voljo" "Ogled vseh dovoljenj za aplikacijo %1$s" "Ogled vseh aplikacij s tem dovoljenjem" "Aplikacije s tem dovoljenjem imajo te možnosti: %1$s" @@ -190,13 +190,13 @@ "Aplikacije s tem dovoljenjem lahko dostopajo do podatkov tipal o vaših vitalnih znakih" "Aplikacije s tem dovoljenjem lahko pošiljajo in berejo sporočila SMS" "Aplikacije s tem dovoljenjem lahko dostopajo do fotografij, predstavnostnih vsebin in datotek v napravi" - "Zadnji dostop: %1$s" - "Trenutno zavrnjeno / zadnji dostop: %1$s" - "Še brez dostopa" + "Zadnja uporaba: %1$s" + "Trenutno zavrnjeno / zadnja uporaba: %1$s" + "Še brez uporabe" "Zavrnjeno / še brez dostopa" "Dovoljeno" "Vedno dovoljeno" - "Dovoljeno samo med uporabo" + "Dovoljeno samo med uporabo aplikacije" "Zavrnjeno" "Podroben pregled uporabe" @@ -224,13 +224,13 @@ %s sekundami "Opomniki za dovoljenja" - "Aplikacija %s je uporabljala vašo lokacijo" + "Aplikacija %s je podatek o lokaciji pridobila v ozadju" "Ta aplikacija lahko vedno dostopa do vaše lokacije. Dotaknite se, če želite spremeniti dovoljenje." "Samo, ko je aplikacija v uporabi" "Aplikacija nima nobenih dovoljenj" "Nobeno dovoljenje ni odvzeto" "Nobena aplikacija nima dovoljenja" - "Dovoljenje ni odvzeto nobeni aplikaciji" + "Dovoljenje ni zavrnjeno nobeni aplikaciji" "Nastavitve" "Storitev %s ima poln dostop do naprave" "Poln dostop do naprave ima toliko aplikacij za ljudi s posebnimi potrebami: %s" @@ -272,8 +272,8 @@ "Želite aplikacijo %1$s nastaviti kot privzeto aplikacijo za preusmerjanje klicev?" "Nobeno dovoljenje ni potrebno" "Privz. apl. za ID klicatelja in nežel. klice" - "Aplik. za ID klicat. in nežel. klice" - "Aplikacije, ki vam omogočajo prepoznavo dohodnih klicev, blokiranje neželene vsebine in avtomatiziranih klicev, uvrščanje neželenih številk na črni seznam itd." + "ID klicatelja in neželeni klici" + "Aplikacije, ki vam omogočajo prepoznavo dohodnih klicev, blokiranje neželenih in avtomatiziranih klicev, uvrščanje številk na seznam blokiranih in drugo" "Želite aplikacijo %1$s nastaviti kot privzeto aplikacijo za ID-je klicateljev in neželene klice?" "Nobeno dovoljenje ni potrebno" "Trenutna privzeta nastavitev" @@ -294,6 +294,8 @@ "Brez" "(privzeta v sistemu)" "Ni aplikacij" + "Izbrano" + "Izbrano – %1$s" "posebni dostop za aplikacije" "Posebni dostop za aplikacije" "Ni posebnega dostopa za aplik." diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml index f75c70ab8..19a7e256a 100644 --- a/res/values-sq/strings.xml +++ b/res/values-sq/strings.xml @@ -210,7 +210,7 @@ 1 sekondë "Alarmet rikujtuese për lejet" - "%s ka përdorur vendndodhjen tënde" + "%s ka marrë vendndodhjen tënde në sfond" "Ky aplikacion mund të qaset gjithmonë te vendndodhja jote. Trokit për ta ndryshuar." "Vetëm kur aplikacioni është në përdorim" "Nuk jepet asnjë leje" @@ -234,12 +234,12 @@ "Nuk ka nevojë për asnjë autorizim" "Aplikacioni i parazgjedhur i telefonit" "Aplikacioni \"Telefoni\"" - "Aplikacionet që të lejojnë të bësh dhe të marrësh telefonata në pajisjen tënde" + "Aplikacione që të lejojnë të bësh dhe të marrësh telefonata në pajisjen tënde" "Dëshiron ta caktosh %1$s si aplikacionin tënd të parazgjedhur të telefonit?" "Merr qasjen tek evidenca e telefonatave dhe dërgon SMS" "Aplikacioni i parazgjedhur i SMS-ve" "Aplikacioni i mesazheve SMS" - "Aplikacionet që të lejojnë të përdorësh numrin e telefonit për të dërguar dhe për të marrë mesazhe të shkurtra me tekst, fotografi, video etj." + "Aplikacione që të lejojnë të përdorësh numrin e telefonit për të dërguar dhe për të marrë mesazhe të shkurtra me tekst, fotografi, video etj." "Dëshiron ta caktosh %1$s si aplikacionin e parazgjedhur për mesazhet SMS?" "Merr qasjen te kontaktet, mesazhet SMS dhe telefoni" "Aplikacioni i parazgjedhur i urgjencës" @@ -249,12 +249,12 @@ "Nuk ka nevojë për asnjë autorizim" "Aplikacioni bazë i parazgjedhur" "Aplikacioni bazë" - "Aplikacionet, të quajtura shpesh nisësit, që zëvendësojnë ekranet bazë në pajisjen tënde Android dhe që të japin qasje te përmbajtjet dhe funksionet e pajisjes sate" + "Aplikacione, të quajtura shpesh \"nisësit\", që zëvendësojnë ekranet bazë në pajisjen tënde Android dhe që të japin qasje te përmbajtjet dhe funksionet e pajisjes sate" "Dëshiron ta caktosh %1$s si aplikacionin e parazgjedhur për ekranin bazë?" "Nuk ka nevojë për asnjë autorizim" "Aplikacioni i parazgjedhur i ridrejtimit të telefonatave" "Aplikacioni i ridrejtimit të telefonatave" - "Aplikacionet që të lejojnë t\'i transferosh telefonatat te një numër tjetër telefoni" + "Aplikacione që të lejojnë t\'i transferosh telefonatat te një numër tjetër telefoni" "Dëshiron ta caktosh %1$s si aplikacionin e parazgjedhur për ridrejtimin e telefonatave?" "Nuk ka nevojë për asnjë autorizim" "Aplikacioni i parazgjedhur për ID-në dhe telefonuesit e bezdisshëm" @@ -280,6 +280,10 @@ "Asnjë" "(Parazgjedhja e sistemit)" "Nuk ka aplikacione" + + + + "qasje e veçantë e aplikacionit" "Qasje e veçantë aplikacioni" "Jo qasje e veçantë aplikacioni" diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml index 1df220ac4..84956137b 100644 --- a/res/values-sr/strings.xml +++ b/res/values-sr/strings.xml @@ -60,7 +60,7 @@ "Нема апликација" "Подешавања локације" "%1$s пружа услуге локације за овај уређај. Приступ локацији можете да измените у подешавањима локације." - "Ако одбијете ову дозволу, основне функције уређаја можда неће више функционисати исправно." + "Ако одбијете ову дозволу, основне функције уређаја можда неће више исправно радити." "Примењује се у складу са смерницама" "Приступ у позадини је онемогућен смерницама" "Приступ у позадини је омогућен смерницама" @@ -217,7 +217,7 @@ %s секунди "Подсетници за дозволе" - "%s користи вашу локацију" + "%s има вашу локацију у позадини" "Ова апликација може увек да приступа локацији. Додирните да бисте то променили." "Само док се апликација користи" "Дозволе нису одобрене" @@ -287,6 +287,8 @@ "Ништа" "(Подразумевана системска)" "Нема апликација" + "Изабрано" + "Изабрано – %1$s" "приступ за специјалну апликацију" "Приступ за спец. апликацију" "Нема приступа за спец. апл." diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml index ce381d2b2..ea3d95bf7 100644 --- a/res/values-sv/strings.xml +++ b/res/values-sv/strings.xml @@ -210,7 +210,7 @@ 1 sekund "Behörighetspåminnelser" - "%s har använt din plats" + "%s har åtkomst till din plats i bakgrunden" "Den här appen har alltid åtkomst till din plats. Tryck här om du vill ändra det." "Endast när appen används" "Inga behörigheter har beviljats" @@ -280,6 +280,8 @@ "Ingen" "(Systemstandard)" "Inga appar" + "Vald" + "Vald – %1$s" "särskild appåtkomst" "Särskild åtkomst för app" "Ingen särskild åtkomst för app" diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml index f5982fe7b..adfc41b00 100644 --- a/res/values-sw/strings.xml +++ b/res/values-sw/strings.xml @@ -210,7 +210,7 @@ Sekunde 1 "Vikumbusho vya ruhusa" - "%s imekuwa ikitumia maelezo ya mahali ulipo" + "%s ilipata mahali ulipo chinichini" "Programu hii inaweza kufikia maelezo ya mahali ulipo kila wakati. Gusa ili ubadilishe." "Wakati programu inatumika pekee" "Hakuna ruhusa zilizotolewa" @@ -280,6 +280,10 @@ "Hakuna" "(Programu chaguomsingi ya mfumo)" "Hakuna programu" + + + + "ufikiaji maalum wa programu" "Ufikiaji wa programu maalum" "Hamna kufikia programu maalum" diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml index 31fa4d37f..3fc2f3b0d 100644 --- a/res/values-ta/strings.xml +++ b/res/values-ta/strings.xml @@ -210,7 +210,8 @@ 1 விநாடி "அனுமதிக்கான நினைவூட்டல்கள்" - "%s உங்கள் இருப்பிடத்தைப் பயன்படுத்துகிறது" + + "எப்பொழுதும் உங்கள் இருப்பிடத்தை இந்த ஆப்ஸால் பயன்படுத்த இயலும். மாற்றத் தட்டவும்." "ஆப்ஸ் உபயோகத்தில் இருக்கும்போது மட்டும்" "எந்த அனுமதிகளும் வழங்கப்படவில்லை" @@ -280,6 +281,10 @@ "ஏதுமில்லை" "(சிஸ்டத்தின் இயல்புநிலை)" "ஆப்ஸ் இல்லை" + + + + "ஆப்ஸிற்கான சிறப்பு அணுகல்" "ஆப்ஸிற்கான சிறப்பு அணுகல்" "ஆப்ஸிற்கு சிறப்பு அணுகல் இல்லை" diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml index 266be2651..242d0f9a3 100644 --- a/res/values-te/strings.xml +++ b/res/values-te/strings.xml @@ -210,7 +210,7 @@ 1 సెకను "అనుమతి రిమైండర్‌లు" - "%s మీ స్థానాన్ని ఉపయోగిస్తోంది" + "మీ స్థానాన్ని %s నేపథ్యంలో ఉపయోగిస్తోంది" "ఈ యాప్ మీ స్థానాన్ని ఎల్లప్పుడూ యాక్సెస్ చేయగలదు. మార్చడానికి నొక్కండి." "యాప్ వినియోగంలో ఉన్నప్పుడు మాత్రమే" "అనుమతులు ఏవీ ఇవ్వలేదు" @@ -280,6 +280,10 @@ "ఏదీ కాదు" "(సిస్టమ్ డిఫాల్ట్)" "ఏ యాప్ లేదు" + + + + "ప్రత్యేక యాప్ యాక్సెస్" "ప్రత్యేక యాప్ యాక్సెస్" "ప్రత్యేక యాప్ యాక్సెస్ లేదు" diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml index 690625f85..8f04d3883 100644 --- a/res/values-th/strings.xml +++ b/res/values-th/strings.xml @@ -144,7 +144,7 @@ "อนุญาตขณะมีการใช้แอปเท่านั้น" "ปฏิเสธ" "สิทธิ์เกี่ยวกับ%1$s" - "สิทธิ์การเข้าถึง%1$sสำหรับแอปนี้" + "สิทธิ์การเข้าถึง \"%1$s\" สำหรับแอปนี้" "%1$s เข้าถึง%2$sเมื่อ %3$sที่ผ่านมา" "%1$s เข้าถึงกิจกรรมการเคลื่อนไหวร่างกายเมื่อ %2$sที่ผ่านมา" "%1$s เข้าถึงปฏิทินเมื่อ %2$sที่ผ่านมา" @@ -170,9 +170,9 @@ "%1$s ไม่ได้เข้าถึง SMS" "%1$s ไม่ได้เข้าถึงพื้นที่เก็บข้อมูล" "ขณะนี้ข้อมูลการเข้าถึงล่าสุดไม่พร้อมใช้งานสำหรับสิทธิ์นี้" - "ดูสิทธิ์ทั้งหมดของ %1$s" + "ดูสิทธิ์ทั้งหมดของ \"%1$s\"" "ดูแอปทั้งหมดที่มีสิทธิ์นี้" - "แอปที่มีสิทธิ์นี้จะ%1$sได้" + "แอปที่มีสิทธิ์นี้จะ%1$s ได้" "แอปที่มีสิทธิ์นี้จะเข้าถึงกิจกรรมการเคลื่อนไหวร่างกายได้ เช่น การเดิน การปั่นจักรยาน การขับรถ การนับจำนวนก้าว และอื่นๆ" "แอปที่มีสิทธิ์นี้จะเข้าถึงปฏิทินของคุณได้" "แอปที่มีสิทธิ์นี้จะอ่านและเขียนประวัติการโทรได้" @@ -210,7 +210,7 @@ 1 วินาที "การช่วยเตือนเกี่ยวกับสิทธิ์" - "%s ใช้ตำแหน่งของคุณ" + "%s เข้าถึงตำแหน่งของคุณอยู่เบื้องหลัง" "แอปนี้เข้าถึงตำแหน่งของคุณได้ตลอดเวลา แตะเพื่อเปลี่ยน" "เมื่อมีการใช้แอปเท่านั้น" "ไม่ได้ให้สิทธิ์ใดเลย" @@ -229,7 +229,7 @@ "มีสิทธิ์เข้าถึง SMS และประวัติการโทร" "แอปเบราว์เซอร์เริ่มต้น" "แอปเบราว์เซอร์" - "แอปที่ให้คุณเข้าถึงลิงก์อินเทอร์เน็ตและจอแสดงผลที่คุณแตะ" + "แอปที่ให้คุณเข้าถึงอินเทอร์เน็ตและแสดงลิงก์ที่คุณแตะ" "ตั้งค่า %1$s เป็นแอปเบราว์เซอร์เริ่มต้นไหม" "ไม่ต้องใช้สิทธิ์" "แอปโทรศัพท์เริ่มต้น" @@ -239,7 +239,7 @@ "มีสิทธิ์เข้าถึงประวัติการโทรและส่ง SMS" "แอป SMS เริ่มต้น" "แอป SMS" - "แอปที่ให้คุณใช้หมายเลขโทรศัพท์เพื่อส่งและรับข้อความ รูปภาพ วิดีโอ และอื่นๆ" + "แอปที่ให้คุณใช้หมายเลขโทรศัพท์เพื่อส่งและรับ SMS, รูปภาพ, วิดีโอ และอื่นๆ" "ตั้งค่า %1$s เป็นแอป SMS เริ่มต้น" "มีสิทธิ์เข้าถึงรายชื่อติดต่อ SMS และโทรศัพท์" "แอปฉุกเฉินเริ่มต้น" @@ -259,7 +259,7 @@ "ไม่ต้องใช้สิทธิ์" "แอปเริ่มต้นสำหรับสกรีนหมายเลขผู้โทรและสแปม" "แอปสกรีนหมายเลขผู้โทรและสแปม" - "แอปที่ให้คุณระบุสายเรียกเข้า บล็อกสแปมและสายจากระบบตอบรับอัตโนมัติ รวมถึงขึ้นบัญชีดำหมายและที่ไม่พึงประสงค์ และอีกมากมาย" + "แอปที่ให้คุณระบุสายเรียกเข้า บล็อกสแปมและสายจากระบบตอบรับอัตโนมัติ รวมถึงขึ้นบัญชีดำหมายเลขที่ไม่พึงประสงค์ และอีกมากมาย" "ตั้งค่า %1$s เป็นแอปเริ่มต้นสำหรับสกรีนหมายเลขผู้โทรและสแปมไหม" "ไม่ต้องใช้สิทธิ์" "แอปเริ่มต้นปัจจุบัน" @@ -280,6 +280,10 @@ "ไม่มี" "(ค่าเริ่มต้นของระบบ)" "ไม่มีแอป" + + + + "สิทธิ์เข้าถึงพิเศษของแอป" "สิทธิ์เข้าถึงพิเศษของแอป" "ไม่มีสิทธิ์เข้าถึงพิเศษของแอป" diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml index db21cb88a..2c21c0818 100644 --- a/res/values-tl/strings.xml +++ b/res/values-tl/strings.xml @@ -210,7 +210,7 @@ %s na segundo "Mga paalala sa pahintulot" - "Ginagamit ng %s ang iyong lokasyon" + "Kinuha ng %s ang iyong lokasyon sa background" "Maa-access ng app na ito ang iyong lokasyon anumang oras. I-tap para baguhin." "Habang ginagamit lang ang app" "Walang pinayagang pahintulot" @@ -280,6 +280,10 @@ "Wala" "(Default ng system)" "Walang app" + + + + "Espesyal na access ng app" "Espesyal na app access" "Walang espesyal na app access" diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml index 54bcd82b6..aa06a945e 100644 --- a/res/values-tr/strings.xml +++ b/res/values-tr/strings.xml @@ -129,7 +129,7 @@ "En yüksek erişim" "Son erişilenler" "Uygulama kullanımına göre sırala" - "Saate göre sırala" + "Zamana göre sırala" ", " "Yenile" @@ -144,7 +144,7 @@ "Yalnızca uygulama kullanılırken izin ver" "Reddet" "%1$s izni" - "Bu uygulamaya %1$s erişimi" + "Bu uygulamanın %1$s erişimine" "%1$s %3$s önce cihazınızın %2$s iznine erişti" "%1$s, %2$s önce fiziksel aktivitenize erişti" "%1$s, %2$s önce takviminize erişti" @@ -169,7 +169,7 @@ "%1$s, sensörlerinize erişmedi" "%1$s, SMS\'inize erişmedi" "%1$s, depolama alanınıza erişmedi" - "Son erişim verisi şu anda bu izin için yok" + "Şu anda bu izin için son erişim verisi yok" "Tüm %1$s izinlerini göster" "Bu izne sahip tüm uygulamaları göster" "Bu izne sahip uygulamalar şunu yapabilir: %1$s" @@ -186,8 +186,8 @@ "Bu izne sahip uygulamalar, cihazınızdaki fotoğraflara, medyalara ve dosyalara erişebilir." "Son erişim: %1$s" "Şu anda reddedildi / Son erişim: %1$s" - "Hiç erişilmedi" - "Reddedildi / Hiç erişilmedi" + "Hiç erişmedi" + "Reddedildi / Hiç erişmedi" "İzin verilenler" "Her zaman izin verilenler" "Yalnızca kullanımdayken izin verilenler" @@ -210,7 +210,7 @@ 1 saniye "İzin hatırlatıcılar" - "%s, konumunuzu kullanıyor" + "%s, arka planda konumunuza erişti" "Bu uygulama, konumunuza her zaman erişebilir. Değiştirmek için dokunun." "Yalnızca uygulama kullanılırken" "Hiçbir izin verilmedi" @@ -280,6 +280,10 @@ "Yok" "(Sistem varsayılanı)" "Uygulama yok" + + + + "özel uygulama erişimi" "Özel uygulama erişimi" "Özel uygulama erişimi yok" diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml index 1cfcf88fb..45bfa7032 100644 --- a/res/values-uk/strings.xml +++ b/res/values-uk/strings.xml @@ -181,7 +181,7 @@ "Додатки з цим дозволом можуть %1$s" "Додатки з цим дозволом мають доступ до даних про вашу фізичну активність (ходьбу, поїздки на велосипеді й автомобілі, кількість кроків тощо)" "Додатки з цим дозволом мають доступ до вашого календаря" - "Додатки з цим дозволом можуть переглядати й записувати ваш журнал викликів" + "Додатки з цим дозволом можуть переглядати й редагувати ваш журнал викликів" "Додатки з цим дозволом можуть робити знімки та записувати відео" "Додатки з цим дозволом мають доступ до ваших контактів" "Додатки з цим дозволом мають доступ до геоданих цього пристрою" @@ -193,10 +193,10 @@ "Останній доступ: %1$s" "Наразі заборонено/останній сеанс доступу: %1$s" "Не отримував доступу" - "Заборонено/не отримував доступу" + "Відхилено/не отримував доступу" "Дозволено" "Завжди дозволено" - "Дозволено лише за активності додатка" + "Дозволено додаткам, які використовуються" "Відхилено" "Переглянути дані про використання" @@ -224,13 +224,13 @@ %s секунди "Нагадування про дозволи" - "%s використовує геодані пристрою" + "Додаток %s отримав доступ до даних про місцезнаходження у фоновому режимі" "Цей додаток завжди має доступ до геоданих пристрою. Торкніться, щоб змінити це." "Лише коли додаток використовується" "Немає наданих дозволів" "Немає відхилених дозволів" - "Немає дозволених додатків" - "Немає додатків, дозвіл для яких було відхилено" + "Немає додатків із дозволом" + "Немає додатків, яким відмовлено" "Налаштування" "Сервіс %s має повний доступ до вашого пристрою" "Додатки зі спеціальними можливостями (%s) мають повний доступ до вашого пристрою" @@ -253,7 +253,7 @@ "Отримує доступ до журналу викликів і надсилання SMS" "Додаток для SMS за умовчанням" "Додаток для SMS" - "Додатки, у яких можна надсилати короткі текстові повідомлення, фотографії, відео й іншими даними зі свого номера телефону" + "Додатки, у яких можна обмінюватися короткими текстовими повідомленнями, фото, відео й іншими даними через свій номер телефону" "Чи має %1$s використовуватись як додаток для SMS за умовчанням?" "Отримує доступ до контактів, SMS і телефона" "Додаток для екстрених викликів за умовчанням" @@ -263,7 +263,7 @@ "Дозволи не потрібні" "Додаток головного екрана за умовчанням" "Додаток головного екрана" - "Додатки (так звані панелі запуску), які заміняють головний екран і дають користувачу доступ до вмісту та функцій пристрою Android" + "Додатки, які заміняють головний екран і забезпечують доступ до вмісту та функцій пристрою Android (так звані панелі запуску)" "Чи має %1$s використовуватись як додаток головного екрана за умовчанням?" "Дозволи не потрібні" "Додаток для переспрямування викликів за умовчанням" @@ -294,6 +294,10 @@ "Немає" "(За умовчанням)" "Немає додатків" + + + + "спеціальний доступ додатка" "Спеціальний доступ" "Немає спеціального доступу" diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml index 31dbe9562..c40c7731a 100644 --- a/res/values-ur/strings.xml +++ b/res/values-ur/strings.xml @@ -37,7 +37,7 @@ "سبھی غیر فعال ہیں" "کوئی بھی غیر فعال نہیں ہے" "اجازت دیں" - "ہر بار اجازت دیں" + "ہر وقت اجازت دیں" "صرف ایپ استعمال کرتے وقت اجازت دیں" "ہر وقت اجازت دیں" "ایپس" @@ -95,7 +95,7 @@ "ڈیش بورڈ" "آخری رسائی: %1$s\nایپ زير استعمال ہونے پر آخری بار رسائی حاصل کی گئی تھی" "آخری رسائی: %1$s\nآخری بار پس منظر میں رسائی حاصل کی گئی تھی" - "کوئی اجازت" + "کوئی بھی اجازت" "کسی بھی وقت" "آخری 7 دن" "آخری 24 گھنٹے" @@ -172,8 +172,8 @@ "آخر بار رسائی کرنے کا ڈیٹا اس اجازت کے لیے اس وقت دستیاب نہیں ہے" "%1$s کی سبھی اجازتیں دیکھیں" "اس اجازت والی سبھی ایپس دیکھیں" - "اس اجازت والی ایپس %1$s کر سکتی ہیں" - "اس اجازت والی اپپس آپ کی جسمانی سرگرمی، جیسے کہ چہل قدمی، بائی سائیکلنگ، ڈرائیونگ، قدموں کی تعداد اور مزید تک رسائی حاصل کر سکتے ہیں" + "اس اجازت والی ایپس یہ کام کر سکتی ہیں: %1$s" + "اس اجازت والی اپپس آپ کی جسمانی سرگرمی، جیسے کہ چہل قدمی، بائی سائیکلنگ، ڈرائیونگ، قدموں کی تعداد اور مزید تک رسائی حاصل کر سکتی ہیں" "اس اجازت والی ایپس کو آپ کے کیلنڈر تک رسائی حاصل ہو سکتی ہیں" "اس اجازت والی ایپس فون کے کال لاگ کو پڑھ اور لکھ سکتی ہیں" "اس اجازت والی ایپس تصاویر لے اور ویڈیو ریکارڈ کر سکتی ہیں" @@ -188,10 +188,10 @@ "حال ہی میں مسترد کردہ / آخری رسائی: %1$s" "کبھی بھی رسائی حاصل نہیں کی" "مسترد کر دیا / کبھی رسائی حاصل نہیں کی" - "اجازت ہے" + "اجازت یافتہ" "ہر وقت اجازت یافتہ" "صرف استعمال کے دوران اجازت ہے" - "مسترد ہو گئی" + "مسترد کردہ" "تفصیلی استعمال دیکھیں" %s دن @@ -210,7 +210,7 @@ 1 سیکنڈ "اجازت کی یاددہانیاں" - "%s آپ کے مقام کا استعمال کر رہی ہے" + "%s نے پس منظر میں آپ کا مقام حاصل کر لیا ہے" "یہ ایپ ہمیشہ آپ کے مقام تک رسائی حاصل کر سکتی ہے۔ تبدیل کرنے کے لیے تھپتھپائیں۔" "صرف اپپ کے زیر استعمال ہونے کے دوران" "کوئی اجازت نہیں دی گئی" @@ -280,6 +280,10 @@ "کوئی نہیں" "(سسٹم ڈیفالٹ)" "کوئی ایپس نہیں ہیں" + + + + "ایپ کی خاص رسائی" "خاص ایپ تک رسائی" "خاص ایپ تک کوئی رسائی نہیں ہے" @@ -300,7 +304,7 @@ "سسٹم اپپ کا استعمال دکھائيں" "اسٹیٹس بار، ڈیش بورڈ اور کسی بھی جگہ پر اجازتوں کے سسٹم اپپ کے استعمال کو شو کریں" "مندرجہ ذیل کے استعمال کو نمایاں کریں" - "اسسٹنٹ محرک پتہ لگانا دکھائیں" + "اسسٹنٹ محرک کا پتہ لگانا دکھائیں" "جب صوتی معاون کو فعال کرنے کے لیے مائیکروفون کا استعمال کیا جائے تو اسٹیٹس بار میں آئیکن دکھائیں" "‏‎<b>%1$s</b>‎ کو آپ کے آلہ پر تصاویر، میڈیا تک رسائی کی اجازت دیں؟" diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml index 374e0b35d..c3d3d7d17 100644 --- a/res/values-uz/strings.xml +++ b/res/values-uz/strings.xml @@ -169,20 +169,20 @@ "%1$s sensorlardan foydalanmadi" "%1$s SMS xabarlaringizga kirmadi" "%1$s xotiradan foydalanmadi" - "Oxirgi kirilgan axborotlar bu ruxsatnomada mavjud emas" + "Bu ruxsatdan foydalanish haqida hech qanday axborot mavjud emas" "%1$s uchun berilgan barcha ruxsatlar" "Bu ruxsatga ega barcha ilovalar" "Bunday ruxsatga ega ilovalar quyidagi amallarni bajara oladi: %1$s" "Bunday ruxsatga ega ilovalar piyoda yurish, velosiped haydash, avtomobil boshqarish, qadamlaringiz soni kabi jismoniy faoliyatingiz haqidagi axborotlarga ham kira oladi" "Bunday ruxsatga ega ilovalar taqvimingizdan foydalana oladi" - "Bunday ruxsatga ega ilovalar telefon chaqiruv jurnalini oʻqiy oladi va unga yoza oladi" - "Bunday ruxsatga ega ilovalar suratga tushira oladi va video yoza oladi" + "Bunday ruxsatga ega ilovalar telefondagi chaqiruvlar jurnaliga kira oladi va uni tahrirlay oladi" + "Bunday ruxsatga ega ilovalar surat va videolar olishi mumkin" "Bunday ruxsatga ega ilovalar kontaktlaringizdan foydalana oladi" "Bunday ruxsatga ega ilovalar bu qurilmaning joylashuv axborotidan foydalana oladi" "Bunday ruxsatga ega ilovalar audio yoza oladi" "Bunday ruxsatga ega ilovalar telefon chaqiruvlarini amalga oshira oladi va boshqara oladi" "Bunday ruxsatga ega ilovalar organizm holati haqidagi sezgichlar axborotlaridan foydalana oladi" - "Bunday ruxsatga ega ilovalar SMS xabarlar yubora va ocha oladi" + "Bunday ruxsatga ega ilovalar SMS xabarlarga kira oladi va yubora oladi" "Bunday ruxsatga ega ilovalar qurilmangizdagi rasm, multimedia va fayllaringizdan foydalana oladi" "Oxirgi marta ishlatilgan: %1$s" "Hozirda rad etilgan / Oxirgi marta ishlatilgan: %1$s" @@ -210,7 +210,7 @@ 1 soniya "Ruxsat eslatmalari" - "%s joylashuvingiz axborotidan foydalanmoqda" + "%s ilova joylashuv axborotingizni orqa fonda oldi" "Bu ilova joylashuv axborotingizdan foydalana oladi. Oʻzgartirish uchun bosing." "Faqat ilova faolligida ruxsat" "Hech qanday ruxsat berilmagan" @@ -248,7 +248,7 @@ "%1$s asosiy favqulodda holatlar ilovasi sifatida sozlansinmi?" "Hech qanday ruxsat zarur emas" "Bosh ekran ilovasi" - "Home ilovasi" + "Bosh ekran ilovasi" "Odatda launcherlar deb nomlanuvchi ilovalar Android qurilmangiz bosh ekranini almashtirib, qurilmangiz kontenti va funksiyalardan foydalanish imkonini beradi" "%1$s asosiy uy ilovasi sifatida sozlansinmi?" "Hech qanday ruxsat zarur emas" @@ -280,6 +280,10 @@ "Hech qanday" "(Birlamchi)" "Hech qanday ilova topilmadi" + + + + "maxsus ilova ruxsatlari" "Maxsus ruxsatlar" "Maxsus ilova ruxsatlari yoʻq" diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml index 614d20502..58d2408fe 100644 --- a/res/values-vi/strings.xml +++ b/res/values-vi/strings.xml @@ -210,7 +210,7 @@ 1 giây "Lời nhắc về quyền" - "%s đã sử dụng thông tin vị trí của bạn" + "%s đã truy cập thông tin vị trí của bạn trong nền" "Ứng dụng này luôn có thể truy cập vào thông tin vị trí của bạn. Hãy nhấn để thay đổi." "Chỉ khi đang sử dụng ứng dụng" "Chưa cấp quyền nào" @@ -280,6 +280,10 @@ "Không có" "(Ứng dụng mặc định của hệ thống)" "Không có ứng dụng nào" + + + + "quyền truy cập ứng dụng đặc biệt" "Quyền truy cập đặc biệt" "Không có quyền truy cập đặc biệt" diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml index 219ad130d..c495bf0fd 100644 --- a/res/values-zh-rCN/strings.xml +++ b/res/values-zh-rCN/strings.xml @@ -210,7 +210,7 @@ 1 秒 "权限提醒" - "%s一直在使用您的位置信息" + "%s在后台获取了您的位置信息" "此应用随时可以使用您的位置信息。点按即可更改。" "仅在使用该应用期间允许" "未允许任何权限" @@ -280,6 +280,10 @@ "无" "(系统默认)" "没有应用" + + + + "特殊应用权限" "特殊应用权限" "没有特殊应用权限" diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml index 6baa78fbb..02066d136 100644 --- a/res/values-zh-rHK/strings.xml +++ b/res/values-zh-rHK/strings.xml @@ -94,7 +94,7 @@ "不明" "資訊主頁" "上次存取時間:%1$s\n上次存取:使用應用程式時" - "上次存取時間:%1$s\n上次存取:背景" + "上次存取時間:%1$s,\n於背景存取" "任何權限" "不限時間" "過去 7 天" @@ -157,18 +157,18 @@ "「%1$s」於 %2$s前存取了您的感應器" "「%1$s」於 %2$s前存取了您的短訊" "「%1$s」於 %2$s前存取了您的儲存空間" - "「%1$s」沒有存取您的%2$s" - "「%1$s」沒有存取您的運動資料" - "「%1$s」沒有存取您的日曆" - "「%1$s」沒有存取您的通話記錄" - "「%1$s」沒有存取您的相機" - "「%1$s」沒有存取您的聯絡人" - "「%1$s」沒有存取您的位置" - "「%1$s」沒有存取您的麥克風" - "「%1$s」沒有存取您的手機" - "「%1$s」沒有存取您的感應器" - "「%1$s」沒有存取您的短訊" - "「%1$s」沒有存取您的儲存空間" + "「%1$s」沒存取過您的%2$s" + "「%1$s」沒存取過您的運動資料" + "「%1$s」沒存取過您的日曆" + "「%1$s」沒存取過您的通話記錄" + "「%1$s」沒存取過您的相機" + "「%1$s」沒存取過您的聯絡人" + "「%1$s」沒存取過您的位置" + "「%1$s」沒存取過您的麥克風" + "「%1$s」沒存取過您的手機" + "「%1$s」沒存取過您的感應器" + "「%1$s」沒存取過您的短訊" + "「%1$s」沒存取過您的儲存空間" "目前無法提供此權限的上次存取資料" "查看「%1$s」的所有權限" "查看擁有此權限的所有應用程式" @@ -187,7 +187,7 @@ "上次存取時間:%1$s" "目前遭拒/上次存取時間:%1$s" "從未存取過" - "遭到拒絕/從未存取過" + "已拒絕/從未存取過" "已允許" "一律允許" "只在使用時允許" @@ -210,12 +210,12 @@ 1 秒 "權限提醒" - "%s在使用您的位置資訊" + "%s在背景存取了您的位置資訊" "此應用程式可隨時存取您的位置資訊。輕按即可變更權限。" "只在使用應用程式時" "不允許任何權限" "沒有拒絕任何權限" - "不允許任何應用程式" + "沒有允許任何應用程式" "沒有拒絕任何應用程式" "設定" "%s可以取得您裝置的完整存取權" @@ -280,6 +280,10 @@ "無" "(系統預設)" "沒有應用程式" + + + + "特別應用程式存取權" "特別應用程式權限" "沒有特別應用程式權限" diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml index 7c8ef70a3..1c8a098d5 100644 --- a/res/values-zh-rTW/strings.xml +++ b/res/values-zh-rTW/strings.xml @@ -210,7 +210,7 @@ 1 秒 "權限提醒" - "「%s」正在使用你的位置資訊" + "「%s」在背景存取了你的位置資訊" "這個應用程式隨時都能存取你的位置資訊。輕觸即可變更設定。" "僅在應用程式使用期間" "未授予任何權限" @@ -280,6 +280,10 @@ "無" "(系統預設)" "沒有可用的應用程式" + + + + "特殊應用程式存取權" "特殊應用程式存取權" "沒有特殊應用程式存取權" @@ -301,6 +305,6 @@ "在狀態列、資訊主頁和其他地方顯示系統應用程式的權限使用情況" "醒目顯示以下應用程式的使用情況" "顯示 Google 助理觸發條件偵測結果" - "使用麥克風啟用語音小幫手時在狀態列顯示相關圖示" + "使用麥克風啟用語音小幫手時,在狀態列顯示相關圖示" "要允許「%1$s」存取裝置中的相片和媒體嗎?" diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml index fc9298412..d66d37009 100644 --- a/res/values-zu/strings.xml +++ b/res/values-zu/strings.xml @@ -210,7 +210,7 @@ %s amasekhondi "Izikhumbuzi zemvume" - "I-%s ibikade isebenzisa indawo yakho" + "%s inendawo yakho ngasemuva" "Lolu hlelo lokusebenza lungahlala lufinyelela indawo yakho. Thepha ukuze ushintshe." "Kuphela ngenkathi uhlelo lokusebenza lusebenza" "Azikho izimvume ezivunyelwe" @@ -280,6 +280,10 @@ "Lutho" "(Okuzenzakalelayo kwesistimu)" "Azikho izinhlelo zokusebenza" + + + + "ukufinyelela kohlelo lokusebenza okukhethekile" "Ukungena kohlelo okukhethekile" "Akukho ukungena okukhethekile" -- GitLab From 81e49b49026ef9ef4cfabd04721e99a58d615e58 Mon Sep 17 00:00:00 2001 From: sqian Date: Thu, 9 May 2019 12:05:08 -0700 Subject: [PATCH 634/701] Clarify the call redirection/screening role strings Test: https://b.corp.google.com/issues/132352331#comment2 Bug: 132352331 Change-Id: Ia8cb72c71ab267a9c6ce4656bc79b9d4cbc47080 --- res/values/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index bc469f08e..c03934daa 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -690,7 +690,7 @@ Call redirecting app - Apps that allow you to forward calls to another phone number + Apps that allow you to forward outgoing calls to another phone number Set %1$s as your default call redirection app? @@ -701,7 +701,7 @@ Caller ID & spam app - Apps that allow you to identify incoming calls, block spam and robocalls, blacklist unwanted numbers, and so on + Apps that allow you to identify calls, block spam and robocalls, and blacklist unwanted numbers Set %1$s as your default caller ID & spam app? -- GitLab From c5c0d8ea964a37bdca54fe6fe2a0c388b705e0b0 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Sat, 11 May 2019 19:05:50 -0700 Subject: [PATCH 635/701] Import translations. DO NOT MERGE Auto-generated-cl: translation import Bug: 64712476 Change-Id: I9185a775bd06b302a212d5e89b6c5842fd6e9ff5 --- res/values-af/strings.xml | 6 ++++-- res/values-am/strings.xml | 6 ++++-- res/values-ar/strings.xml | 14 +++++++------- res/values-as/strings.xml | 6 ++++-- res/values-az/strings.xml | 6 ++++-- res/values-b+sr+Latn/strings.xml | 6 ++++-- res/values-be/strings.xml | 12 ++++++------ res/values-bg/strings.xml | 12 ++++++------ res/values-bn/strings.xml | 12 ++++++------ res/values-bs/strings.xml | 6 ++++-- res/values-ca/strings.xml | 8 +++++--- res/values-cs/strings.xml | 12 ++++++------ res/values-da/strings.xml | 12 ++++++------ res/values-de/strings.xml | 6 ++++-- res/values-el/strings.xml | 6 ++++-- res/values-en-rAU/strings.xml | 6 ++++-- res/values-en-rCA/strings.xml | 6 ++++-- res/values-en-rGB/strings.xml | 6 ++++-- res/values-en-rIN/strings.xml | 6 ++++-- res/values-en-rXC/strings.xml | 4 ++-- res/values-es-rUS/strings.xml | 12 ++++++------ res/values-es/strings.xml | 6 ++++-- res/values-et/strings.xml | 8 +++++--- res/values-eu/strings.xml | 12 ++++++------ res/values-fa/strings.xml | 12 ++++++------ res/values-fi/strings.xml | 12 ++++++------ res/values-fr-rCA/strings.xml | 6 ++++-- res/values-fr/strings.xml | 12 ++++++------ res/values-gl/strings.xml | 12 ++++++------ res/values-gu/strings.xml | 12 ++++++------ res/values-hi/strings.xml | 12 ++++++------ res/values-hr/strings.xml | 6 ++++-- res/values-hu/strings.xml | 12 ++++++------ res/values-hy/strings.xml | 16 ++++++++-------- res/values-in/strings.xml | 6 ++++-- res/values-is/strings.xml | 6 ++++-- res/values-it/strings.xml | 6 ++++-- res/values-iw/strings.xml | 6 ++++-- res/values-ja/strings.xml | 12 ++++++------ res/values-ka/strings.xml | 6 ++++-- res/values-kk/strings.xml | 12 ++++++------ res/values-km/strings.xml | 12 ++++++------ res/values-kn/strings.xml | 12 ++++++------ res/values-ko/strings.xml | 12 ++++++------ res/values-ky/strings.xml | 12 ++++++------ res/values-lo/strings.xml | 6 ++++-- res/values-lt/strings.xml | 12 ++++++------ res/values-lv/strings.xml | 12 ++++++------ res/values-mk/strings.xml | 6 ++++-- res/values-ml/strings.xml | 6 ++++-- res/values-mn/strings.xml | 12 ++++++------ res/values-mr/strings.xml | 8 +++++--- res/values-ms/strings.xml | 12 ++++++------ res/values-my/strings.xml | 6 ++++-- res/values-nb/strings.xml | 12 ++++++------ res/values-ne/strings.xml | 12 ++++++------ res/values-nl/strings.xml | 6 ++++-- res/values-or/strings.xml | 6 ++++-- res/values-pa/strings.xml | 12 ++++++------ res/values-pl/strings.xml | 12 ++++++------ res/values-pt-rBR/strings.xml | 6 ++++-- res/values-pt-rPT/strings.xml | 6 ++++-- res/values-pt/strings.xml | 6 ++++-- res/values-ro/strings.xml | 12 ++++++------ res/values-ru/strings.xml | 12 ++++++------ res/values-si/strings.xml | 6 ++++-- res/values-sk/strings.xml | 12 ++++++------ res/values-sl/strings.xml | 6 ++++-- res/values-sq/strings.xml | 12 ++++++------ res/values-sr/strings.xml | 6 ++++-- res/values-sv/strings.xml | 6 ++++-- res/values-sw/strings.xml | 12 ++++++------ res/values-ta/strings.xml | 9 +++++---- res/values-te/strings.xml | 6 ++++-- res/values-th/strings.xml | 14 +++++++------- res/values-tl/strings.xml | 12 ++++++------ res/values-tr/strings.xml | 12 ++++++------ res/values-uk/strings.xml | 16 ++++++++-------- res/values-ur/strings.xml | 6 ++++-- res/values-uz/strings.xml | 12 ++++++------ res/values-vi/strings.xml | 14 +++++++------- res/values-zh-rCN/strings.xml | 12 ++++++------ res/values-zh-rHK/strings.xml | 12 ++++++------ res/values-zh-rTW/strings.xml | 12 ++++++------ res/values-zu/strings.xml | 12 ++++++------ 85 files changed, 439 insertions(+), 362 deletions(-) diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml index 296fcbada..d5fa8453c 100644 --- a/res/values-af/strings.xml +++ b/res/values-af/strings.xml @@ -254,12 +254,14 @@ "Geen toestemmings is nodig nie" "Oproepherleiding-verstekprogram" "Oproepherleidingprogram" - "Programme wat jou toelaat om oproepe na \'n ander foonnommer aan te stuur" + + "Stel %1$s as jou oproepherleiding-verstekprogram?" "Geen toestemmings is nodig nie" "Verstekbeller-ID en strooiposprogram" "Beller-ID en strooiposprogram" - "Programme wat jou toelaat om inkomende oproepe te identifiseer, strooipos en robotoproepe te blokkeer, ongewenste nommers te swartlys, en so aan" + + "Stel %1$s as jou verstekbeller-ID en -strooiposprogram?" "Geen toestemmings is nodig nie" "Huidige verstek" diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml index bcd7436d0..567acc6c2 100644 --- a/res/values-am/strings.xml +++ b/res/values-am/strings.xml @@ -254,12 +254,14 @@ "ምንም ፈቃዶች አያስፈልጉም" "ነባሪ የጥሪ አቅጣጫ ማዞሪያ መተግበሪያ" "የጥሪ ማዞሪያ መተግበሪያ" - "ወደ ሌላ ስልክ ቁጥር ጥሪዎችን እንዲያስተላልፉ የሚፈቀድልዎት መተግበሪያዎች" + + "%1$s እንደ የእርስዎ ነባሪ የጥሪ ዳግም አቅጣጫ ማዞሪያ መተግበሪያ ይቀናበር?" "ምንም ፈቃዶች አያስፈልጉም" "ነባሪ የደዋይ መታወቂያ እና የአይፈለጌ መልእክት መተግበሪያ" "የደዋይ መታወቂያ እና የአይፈለጌ መልዕክት መተግበሪያ" - "ገቢ ጥሪዎችን ለይተው እንዲያውቁ፣ አይፈለጌ መልዕክትን እና የሮቦት የስልክ ጥሪዎችን እንዲያግዱ፣ የማይፈልጉ ቁጥሮችን በጥቁር መዝገብ እንዲመዘግቡ እና ወዘተ የሚፈቅዱልዎት መተግበሪያዎች" + + "%1$s እንደ የእርስዎ ነባሪ የደዋይ መታወቂያ እና የአይፈልጌ መተግበሪያ ይቀናበር?" "ምንም ፈቃዶች አያስፈልጉም" "አሁን ያለ ነባሪ" diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml index 9a6994156..f9d52323b 100644 --- a/res/values-ar/strings.xml +++ b/res/values-ar/strings.xml @@ -282,12 +282,14 @@ "لا يجب تقديم أذونات." "تطبيق إعادة توجيه المكالمات التلقائي" "تطبيق إعادة توجيه المكالمات" - "التطبيقات التي تتيح لك إمكانية إعادة توجيه المكالمات إلى رقم هاتف آخر" + + "هل تريد ضبط %1$s باعتباره تطبيق إعادة توجيه المكالمات التلقائي؟" "لا يجب تقديم أذونات." "التطبيق التلقائي لإظهار رقم المتّصل والرسائل غير المرغوب" "تطبيق إظهار رقم المتّصل والرسائل غير المرغوب فيها" - "التطبيقات التي تتيح لك الاطّلاع على المكالمات الواردة وحظر الرسائل غير المرغوب فيها والمكالمات المسجّلة وإضافة الأرقام غير المرغوب فيها إلى قائمة سوداء، وما إلى ذلك" + + "هل تريد ضبط %1$s باعتباره التطبيق التلقائي لإظهار رقم المتّصل والمحتوى غير المرغوب فيه؟" "لا يجب تقديم أذونات." "التطبيق التلقائي الحالي" @@ -305,13 +307,11 @@ "المزيد من الإعدادات التلقائية" "فتح الروابط" "التطبيقات التلقائية للعمل" - "بدون" + "غير محدَّد" "(الإعداد التلقائي للنظام)" "ليست هناك تطبيقات." - - - - + "التطبيق المُختار" + "التطبيق المُختار - %1$s" "أذونات خاصة للتطبيقات" "أذونات خاصة للتطبيقات" "لا إذن وصول خاص إلى التطبيق." diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml index 18378f08b..5fff8769a 100644 --- a/res/values-as/strings.xml +++ b/res/values-as/strings.xml @@ -254,12 +254,14 @@ "কোনো অনুমতিৰ প্ৰয়োজন নাই" "ডিফ’ল্ট কল ৰিডাইৰেক্ট কৰা এপ্" "কল ৰিডাইৰেক্ট কৰা এপ্" - "যিবোৰ এপে আপোনাক এটা ফ’ন নম্বৰৰ পৰা আন এটালৈ কল ফ’ৰৱাৰ্ড কৰাৰ অনুমতি দিয়ে" + + "%1$sক আপোনাৰ ডিফ’ল্ট কল্ ৰিডাইৰেক্ট কৰা এপ্ হিচাপে ছেট কৰিবনে?" "কোনো অনুমতিৰ প্ৰয়োজন নাই" "ডিফ’ল্ট কলাৰ আইডি & স্পাম এপ্" "কলাৰ আইডি আৰু স্পাম এপ্" - "যিবোৰ এপে আপোনাক অন্তৰ্গামী কল চিনাক্ত কৰিবলৈ, স্পাম, ৰ’ব’কল আৰু অনাকাংক্ষিত নম্বৰ অৱৰোধ কৰিবলৈ অনুমতি দিয়ে" + + "%1$sক আপোনাৰ ডিফ’ল্ট কলাৰ আই.ডি আৰু স্পাম এপ্ হিচাপে ছেট কৰিবনে?" "কোনো অনুমতিৰ প্ৰয়োজন নাই" "বৰ্তমানৰ ডিফ’ল্ট" diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml index f5fe6c7f9..26f2ea39b 100644 --- a/res/values-az/strings.xml +++ b/res/values-az/strings.xml @@ -254,12 +254,14 @@ "İcazəyə ehtiyac yoxdur" "Defolt zəng yönləndirmə tətbiqi" "Zəng yönləndirmə tətbiqi" - "Zəngləri başqa telefon nömrəsinə yönləndirməyinizə icazə verən tətbiqlər" + + "%1$s defolt zəng yönləndirmə tətbiqi olaraq ayarlansın?" "İcazəyə ehtiyac yoxdur" "Defolt zəng edənin ID-si & spam tətbiqi" "Zəng ID-si & spam tətbiqi" - "Gələn zəngləri müəyyən etməyə, spam və avtomatik zəngləri blok etməyə, lazımsız nömrələri qara siyahıya salmağa və daha çoxuna icazə verən tətbiqlər" + + "%1$s defolt zəng edənin ID-si və spam tətbiqi olaraq ayarlansın?" "İcazəyə ehtiyac yoxdur" "Cari defolt" diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml index d47e75f9f..8baa91c92 100644 --- a/res/values-b+sr+Latn/strings.xml +++ b/res/values-b+sr+Latn/strings.xml @@ -261,12 +261,14 @@ "Nije potrebna nijedna dozvola" "Podraz. apl. za preus. poziva" "Apl. za preusmeravanje poziva" - "Aplikacije koje vam omogućavaju da prosleđujete pozive na drugi broj telefona" + + "Želite li da podesite %1$s kao podrazumevanu aplikaciju za preusmeravanje poziva?" "Nije potrebna nijedna dozvola" "Podraz. apl. za ID poziv. i nepož. poruke" "Apl. za ID poz. i nepož. poz." - "Aplikacije koje vam omogućavaju da identifikujete pozive, blokirate nepoželjne i automatizovane pozive, blokirate neželjene brojeve i drugo" + + "Želite li da podesite %1$s kao podrazumevanu aplikaciju za ID pozivaoca i nepoželjne poruke?" "Nije potrebna nijedna dozvola" "Trenutno podrazumevana" diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml index af00f7da1..30a2cb746 100644 --- a/res/values-be/strings.xml +++ b/res/values-be/strings.xml @@ -268,12 +268,14 @@ "Дазволы не патрэбныя" "Праграма перанакіравання" "Перанакіраванне выклікаў" - "Праграмы, якія дазваляюць вам пераадрасоўваць выклікі на іншы нумар тэлефона" + + "Прызначыць \"%1$s\" стандартнай праграмай для перанакіравання выклікаў?" "Дазволы не патрэбныя" "Праграма для ідэнтыфікацыі абанента і спама" "Ідэнтыфікатар абанента і спам" - "Праграмы, якія дазваляюць вам вызначаць уваходныя выклікі, блакіраваць спам і аўтаматызаваныя выклікі, уносіць непажаданыя нумары ў чорны спіс і гэтак далей" + + "Прызначыць \"%1$s\" стандартнай праграмай для ідэнтыфікацыі абанента і спама?" "Дазволы не патрэбныя" "Цяперашняя стандартная" @@ -294,10 +296,8 @@ "Няма" "(Стандартная сістэмная)" "Няма праграм" - - - - + "Выбрана" + "Выбрана – %1$s" "спецыяльны доступ да праграм" "Спецыяльны доступ да праграм" "Няма доступу да праграм" diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml index ed1ffa29a..714a43c69 100644 --- a/res/values-bg/strings.xml +++ b/res/values-bg/strings.xml @@ -254,12 +254,14 @@ "Не са необходими разрешения" "Станд. прил. за пренас. на обажд." "Прил. за пренас. на обаждания" - "Приложения, които ви дават възможност да пренасочвате обажданията към друг телефонен номер" + + "Да се зададе ли %1$s като стандартно приложение за пренасочване на обажданията?" "Не са необходими разрешения" "Станд. прил. за идент. на обаждащия се и спам" "Идент. на обаждащия се и спам" - "Приложения, които ви дават възможност да идентифицирате входящите обаждания, да блокирате спам и автоматизирани обаждания, да добавяте нежелани номера в черния списък и др." + + "Да се зададе ли %1$s като стандартно приложение за идентификатор на обаждащия се и спам?" "Не са необходими разрешения" "Текущо стандартно приложение" @@ -280,10 +282,8 @@ "Няма" "(Стандартно за системата)" "Няма приложения" - - - - + "Избрано" + "Избрано – %1$s" "специален достъп за приложението" "Специален достъп за прилож." "Няма спец. достъп за прилож." diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml index 0ed2eb725..5c517490f 100644 --- a/res/values-bn/strings.xml +++ b/res/values-bn/strings.xml @@ -254,12 +254,14 @@ "কোনও অনুমতির প্রয়োজন নেই" "ডিফল্ট কল রিডাইরেক্টের অ্যাপ" "কল রিডাইরেক্ট করার অ্যাপ" - "এমন অ্যাপ যা আপনাকে অন্য ফোন নম্বরে কল ফরওয়ার্ড করতে দেয়" + + "%1$s অ্যাপকে আপনার ডিফল্ট কল রিডাইরেক্ট করার অ্যাপ হিসেবে সেট করতে চান?" "কোনও অনুমতির প্রয়োজন নেই" "ডিফল্ট কলার আইডি ও স্প্যাম অ্যাপ" "কলার আইডি ও স্প্যাম অ্যাপ" - "এমন অ্যাপ যা আপনাকে ইনকামিং কল শনাক্ত করা, স্প্যাম ও রোবোকল ব্লক করা, অবাঞ্ছিত নম্বর কালোতালিকাভুক্ত করা সহ আরও অনেক কিছু করতে সাহায্য করে" + + "%1$s অ্যাপকে আপনার ডিফল্ট কলার আইডি ও স্প্যাম অ্যাপ হিসেবে সেট করতে চান?" "কোনও অনুমতির প্রয়োজন নেই" "বর্তমান ডিফল্ট" @@ -280,10 +282,8 @@ "কোনওটিই নয়" "(সিস্টেম ডিফল্ট)" "কোনও অ্যাপ নেই" - - - - + "বেছে নেওয়া হয়েছে" + "বেছে নেওয়া হয়েছে - %1$s" "অ্যাপের বিশেষ অ্যাক্সেস" "অ্যাপের বিশেষ অ্যাক্সেস" "অ্যাপের বিশেষ অ্যাক্সেস নেই" diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml index 0f4e9c8bb..a1e3c24be 100644 --- a/res/values-bs/strings.xml +++ b/res/values-bs/strings.xml @@ -261,12 +261,14 @@ "Nije potrebno odobrenje" "Zadana apl. za preusm. poziva" "Apl. za preusmjeravanje poziva" - "Aplikacije kojima dozvoljavate prosljeđivanje poziva na drugi broj telefona" + + "Postaviti aplikaciju %1$s kao zadanu aplikaciju za preusmjeravanje poziva?" "Nije potrebno odobrenje" "Zadana apl. za prikaz ID-a poziv./neželj. poz." "Apl. za prikaz ID-a pozivaoca i blok. neželj. poruka" - "Aplikacije koje vam omogućavaju identificiranje dolaznih poziva, blokiranje neželjenih i automatiziranih poziva, blokiranje neželjenih brojeva i drugo" + + "Postaviti aplikaciju %1$s kao zadanu aplikaciju za prikaz ID-a pozivaoca i blokadu neželjenih poziva?" "Nije potrebno odobrenje" "Trenutno zadano" diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml index 0d5fc456a..35de0cfd1 100644 --- a/res/values-ca/strings.xml +++ b/res/values-ca/strings.xml @@ -161,7 +161,7 @@ "%1$s no ha accedit a l\'activitat física" "%1$s no ha accedit al calendari" "%1$s no ha accedit als registres de trucades" - "%1$s no ha accedit a la càmera" + "%1$s no ha accedit a la teva càmera" "%1$s no ha accedit als contactes" "%1$s no ha accedit a la ubicació" "%1$s no ha accedit al micròfon" @@ -254,12 +254,14 @@ "No calen permisos" "Aplicació predeterminada per redirigir trucades" "Aplicació per redirigir trucades" - "Aplicacions que et permeten desviar trucades a altres números de telèfon" + + "Vols establir %1$s com a aplicació de desviació de trucades predeterminada?" "No calen permisos" "App predeterminada ID trucades i filtre trucades brossa" "Aplicació ID trucades i filtre trucades brossa" - "Aplicacions que et permeten identificar les trucades entrants, bloquejar les trucades brossa i automàtiques, afegir els números que no vulguis que et truquin a una llista negra, entre d\'altres" + + "Vols establir %1$s com a aplicació predeterminada per identificar trucades i filtrar trucades brossa?" "No calen permisos" "Predeterminada actualment" diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml index d1bb3db0a..2d9b12e37 100644 --- a/res/values-cs/strings.xml +++ b/res/values-cs/strings.xml @@ -268,12 +268,14 @@ "Není potřeba žádné oprávnění" "Výchozí ap. na přesměr. hovorů" "Aplikace k přesměrování hovorů" - "Aplikace, které vám umožňují přesměrovat hovory na jiné číslo" + + "Nastavit %1$s jako výchozí aplikaci na přesměrování hovorů?" "Není potřeba žádné oprávnění" "Výchozí ap. na ID volajícího a redukci spamu" "Ap. na ID volajícího a spam" - "Aplikace, které umožňují identifikovat příchozí hovory, blokovat spam a automatické hovory, vytvořit seznam zakázaných čísel apod." + + "Nastavit %1$s jako výchozí aplikaci k identifikaci volajícího a prevenci spamu?" "Není potřeba žádné oprávnění" "Aktuálně výchozí" @@ -294,10 +296,8 @@ "Žádné" "(Výchozí nastavení systému)" "Žádné aplikace" - - - - + "Vybráno" + "Vybráno – %1$s" "přístup ke speciálním aplikacím" "Přístup ke spec. aplikacím" "Žádný přístup ke spec. aplik." diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml index 7f4eeae23..5a8935e6b 100644 --- a/res/values-da/strings.xml +++ b/res/values-da/strings.xml @@ -254,12 +254,14 @@ "Der kræves ingen tilladelser" "Standardapp til opkaldsviderestilling" "App til opkaldsviderestilling" - "Apps, der giver dig mulighed for at viderestille opkald til et andet telefonnummer" + + "Vil du angive %1$s som din standardapp til opkaldsviderestilling?" "Der kræves ingen tilladelser" "Standardapp til Vis nummer og spam" "App til Vis nummer og spam" - "Apps, der giver dig mulighed for at identificere indgående opkald, blokere spam og automatiske opkald, sortliste uønskede numre osv." + + "Vil du angive %1$s som din standardapp til Vis nummer og spam?" "Der kræves ingen tilladelser" "Nuværende standardapp" @@ -280,10 +282,8 @@ "Ingen" "(Systemstandard)" "Ingen apps" - - - - + "Valgt" + "Valgt – %1$s" "særlig appadgang" "Særlig appadgang" "Ingen særlig appadgang" diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index 72e38fc1f..f4197661a 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -254,12 +254,14 @@ "Keine Berechtigungen erforderlich" "Standard-App für Anrufweiterleitung" "App zur Anrufweiterleitung" - "Apps, die die Weiterleitung von Anrufen an eine andere Telefonnummer erlauben" + + "%1$s als Standard-App für Anrufweiterleitung festlegen?" "Keine Berechtigungen erforderlich" "Standard-App für Anrufer-ID und Spam" "Anrufer-ID- und Spam-App" - "Apps, mit denen du u. a. eingehende Anrufe erkennen, Spam- und automatisierte Anrufe blockieren und unerwünschte Nummern sperren kannst" + + "%1$s als standardmäßige Anrufer-ID- und Spam-App festlegen?" "Keine Berechtigungen erforderlich" "Aktueller Standard" diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml index 5169e0889..c538e18c3 100644 --- a/res/values-el/strings.xml +++ b/res/values-el/strings.xml @@ -254,12 +254,14 @@ "Δεν απαιτούνται άδειες" "Προεπ. εφαρμ. ανακατ. κλήσεων" "Εφαρμογή ανακατεύθ. κλήσεων" - "Εφαρμογές που σας επιτρέπουν να προωθήσετε κλήσεις σε έναν άλλο αριθμό τηλεφώνου" + + "Ορισμός εφαρμογής %1$s ως προεπιλεγμένης εφαρμογής ανακατεύθυνσης κλήσεων;" "Δεν απαιτούνται άδειες" "Προεπ. εφαρ. αναγνώρισης κλήσης/ανεπ. περιεχ." "Εφ. αναγν. κλήσης/προστ. από ανεπιθ. περιεχ." - "Εφαρμογές που σας επιτρέπουν να προσδιορίσετε τις εισερχόμενες κλήσεις, να αποκλείσετε τα ανεπιθύμητα μηνύματα και τις αυτοματοποιημένες κλήσεις, να προσθέσετε ανεπιθύμητους αριθμούς στη μαύρη λίστα κ.λπ." + + "Ορισμός εφαρμογής %1$s ως προεπιλεγμένης εφαρμογής αναγνώρισης κλήσης και ανεπιθύμητου περιεχομένου;" "Δεν απαιτούνται άδειες" "Τρέχουσα προεπιλογή" diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml index 2bcbdaad7..6445d396a 100644 --- a/res/values-en-rAU/strings.xml +++ b/res/values-en-rAU/strings.xml @@ -254,12 +254,14 @@ "No permissions needed" "Default call redirecting app" "Call redirecting app" - "Apps that allow you to forward calls to another phone number" + + "Set %1$s as your default call redirection app?" "No permissions needed" "Default caller ID & spam app" "Caller ID & spam app" - "Apps that allow you to identify incoming calls, block spam and robocalls, blacklist unwanted numbers and so on" + + "Set %1$s as your default caller ID & spam app?" "No permissions needed" "Current default" diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml index 2bcbdaad7..6445d396a 100644 --- a/res/values-en-rCA/strings.xml +++ b/res/values-en-rCA/strings.xml @@ -254,12 +254,14 @@ "No permissions needed" "Default call redirecting app" "Call redirecting app" - "Apps that allow you to forward calls to another phone number" + + "Set %1$s as your default call redirection app?" "No permissions needed" "Default caller ID & spam app" "Caller ID & spam app" - "Apps that allow you to identify incoming calls, block spam and robocalls, blacklist unwanted numbers and so on" + + "Set %1$s as your default caller ID & spam app?" "No permissions needed" "Current default" diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml index 2bcbdaad7..6445d396a 100644 --- a/res/values-en-rGB/strings.xml +++ b/res/values-en-rGB/strings.xml @@ -254,12 +254,14 @@ "No permissions needed" "Default call redirecting app" "Call redirecting app" - "Apps that allow you to forward calls to another phone number" + + "Set %1$s as your default call redirection app?" "No permissions needed" "Default caller ID & spam app" "Caller ID & spam app" - "Apps that allow you to identify incoming calls, block spam and robocalls, blacklist unwanted numbers and so on" + + "Set %1$s as your default caller ID & spam app?" "No permissions needed" "Current default" diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml index 2bcbdaad7..6445d396a 100644 --- a/res/values-en-rIN/strings.xml +++ b/res/values-en-rIN/strings.xml @@ -254,12 +254,14 @@ "No permissions needed" "Default call redirecting app" "Call redirecting app" - "Apps that allow you to forward calls to another phone number" + + "Set %1$s as your default call redirection app?" "No permissions needed" "Default caller ID & spam app" "Caller ID & spam app" - "Apps that allow you to identify incoming calls, block spam and robocalls, blacklist unwanted numbers and so on" + + "Set %1$s as your default caller ID & spam app?" "No permissions needed" "Current default" diff --git a/res/values-en-rXC/strings.xml b/res/values-en-rXC/strings.xml index ed4e15c4d..cf78eb791 100644 --- a/res/values-en-rXC/strings.xml +++ b/res/values-en-rXC/strings.xml @@ -254,12 +254,12 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‏‎‏‎‏‏‏‎‏‏‎‏‏‎‎‏‏‎‏‏‎‏‎‏‏‏‎‏‎‎‎‏‎‏‏‎‏‏‏‎‎‏‏‎‎‎‎‎‏‎‎‏‏‎‏‎No permissions needed‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‏‏‎‏‎‏‎‎‏‏‎‎‎‎‏‎‎‎‎‏‎‎‏‏‏‎‎‏‏‎‏‎‏‏‎‎‏‎‎‏‏‏‎‏‏‎‎‏‎‎‎‎‏‎Default call redirecting app‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‏‏‏‎‎‎‎‏‏‎‏‎‎‏‏‏‎‎‏‏‎‏‎‏‎‏‎‎‎‎‎‎‎‎‎‏‏‎‏‏‏‏‎‎‏‎‎‎‎‎‎‎‎‎Call redirecting app‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‎‎‏‏‎‏‏‎‎‎‏‎‎‎‎‏‎‏‎‏‎‏‎‎‎‎‎‏‏‏‏‎‎‏‎‎‎‏‎‏‏‎‏‎‎‏‏‎‎‎‏‏‎‎‎‏‎Apps that allow you to forward calls to another phone number‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‏‎‏‎‏‏‎‎‏‏‎‏‏‎‏‏‏‎‎‎‏‎‏‏‏‏‎‏‎‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‏‎‏‎‏‏‏‏‏‎‏‏‎Apps that allow you to forward outgoing calls to another phone number‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‎‏‏‏‏‎‎‏‏‎‏‏‎‏‏‏‏‏‎‏‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‎‎‏‏‎‎‏‎‏‎‎‎‎‏‏‏‎Set ‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ as your default call redirection app?‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‏‏‎‎‏‎‎‏‎‎‏‎‎‎‎‎‎‎‎‏‏‎‏‎‎‏‎‏‎‎‏‏‏‏‎‎‎‎‏‎‏‏‏‏‏‎‎‎‏‏‎‎‎‎‏‎No permissions needed‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‏‏‏‏‎‏‏‎‏‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‏‎‏‏‎‏‎‏‎‏‎‎‏‏‎‏‏‎‎‎‏‎‎‏‏‏‏‎‏‎‎Default caller ID & spam app‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‏‎‏‎‏‏‏‎‎‎‏‎‏‏‎‏‎‏‏‎‎‎‏‎‏‏‎‏‏‏‏‎‎‎‏‎‎‎‏‏‏‎‏‎‎‎‏‎‎‎‎‏‎Caller ID & spam app‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‏‏‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‏‏‎‎Apps that allow you to identify incoming calls, block spam and robocalls, blacklist unwanted numbers, and so on‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‎‎‎‎‎‏‎‏‎‏‏‎‎‏‏‏‏‎‎‎‎‏‏‏‎‎‏‏‏‏‏‎‏‎‎‎‏‏‏‏‎‎Apps that allow you to identify calls, block spam and robocalls, and blacklist unwanted numbers‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‏‎‎‎‏‏‎‎‏‏‏‏‏‏‎‏‎‏‏‎‏‏‎‎‏‎‏‏‎‎‏‏‎‎‎‏‎‏‎‎‎‎‎‏‏‎‎‎‎‏‎‏‏‎‏‎Set ‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ as your default caller ID & spam app?‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‎‏‎‏‎‎‎‎‏‎‏‎‎‏‏‎‏‎‏‎‏‎‎‏‎‏‏‏‏‎‎‏‎‎‏‎‎‎‎‎‎‎‏‏‎‎‎‎‎‏‏‎‎No permissions needed‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎‎‎‎‎‎‎‏‎‎‏‎‏‏‎‎‎‎‏‎‏‎‏‏‏‏‎‎‏‏‎‎‏‏‏‏‎‎‏‏‎‎‏‏‏‎‎‏‎‎‏‏‎‎Current default‎‏‎‎‏‎" diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml index fa0de8c04..e52e10a87 100644 --- a/res/values-es-rUS/strings.xml +++ b/res/values-es-rUS/strings.xml @@ -254,12 +254,14 @@ "No se requieren permisos" "App de redireccionamiento" "App para desviar llamadas" - "Apps que te permiten desviar llamadas a otro número de teléfono" + + "¿Quieres establecer %1$s como tu app de redireccionamiento de llamadas predeterminada?" "No se requieren permisos" "App de ID de llamada y spam predeterminada" "App de ID de llamada y spam" - "Apps que te permiten identificar llamadas entrantes, bloquear spam y llamadas automáticas, colocar números no deseados en la lista negra y mucho más" + + "¿Quieres establecer %1$s como tu app de identificador de llamada y spam predeterminada?" "No se requieren permisos" "App predeterminada actualmente" @@ -280,10 +282,8 @@ "Ninguna" "(Predeterminada de sistema)" "Sin apps" - - - - + "Seleccionada" + "Se seleccionó: %1$s" "Acceso especial a apps" "Acceso especial a apps" "No hay acceso especial a apps" diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index 18579511f..4300a546d 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -254,12 +254,14 @@ "No se necesita ningún permiso" "App redirección llamadas predet." "App de redirección de llamadas" - "Son las aplicaciones que te permiten reenviar llamadas a otro número de teléfono" + + "¿Quieres establecer a %1$s como tu aplicación de redirección de llamadas predeterminada?" "No se necesita ningún permiso" "Aplicación de filtro de ID de llamada y spam" "App de filtro ID llamadas y spam" - "Son las aplicaciones que te permiten identificar las llamadas entrantes, bloquear spam y llamadas automatizadas, crear una lista con números no deseados, etc." + + "¿Quieres establecer a %1$s como tu aplicación predeterminada de filtro de ID de llamada y spam?" "No se necesita ningún permiso" "Predeterminada" diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml index abea81cf0..402b2d762 100644 --- a/res/values-et/strings.xml +++ b/res/values-et/strings.xml @@ -254,12 +254,14 @@ "Lube ei ole vaja" "Kõnede suunamise vaikerakendus" "Kõnede ümbersuunamise rakendus" - "Rakendused, mis võimaldavad teil kõnesid teisele telefoninumbrile suunata" + + "Kas soovite määrata rakenduse %1$s kõnede suunamise vaikerakenduseks?" "Lube ei ole vaja" "Helistaja ID ja rämpskõnede vaikerakendus" "Helistaja ID ja rämpskõned" - "Rakendused, mis võimaldavad teil tuvastada sissetulevaid kõnesid, blokeerida rämps- ja robotkõnesid, lisada soovimatuid numbreid musta nimekirja jms" + + "Kas soovite määrata rakenduse %1$s helistaja ID ja rämpskõnede vaikerakenduseks?" "Lube ei ole vaja" "Praegune vaikeseade" @@ -268,7 +270,7 @@ "vaikerakendused" "Selge" "Privaatsusseaded" - "Rakendused, mis kasutavad üksusi %s" + "Rakendused, mis kasutavad funktsiooni %s" ", " " ja " "Seaded" diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml index 26d209374..cf9e132fe 100644 --- a/res/values-eu/strings.xml +++ b/res/values-eu/strings.xml @@ -254,12 +254,14 @@ "Ez du behar baimenik" "Deiak desbideratzeko aplikazio lehenetsia" "Deiak birbideratzeko aplikazioa" - "Baimena duten aplikazioek beste telefono-zenbaki batera birbidaltzen dituzten deiak" + + "%1$s ezarri nahi duzu deiak birbideratzeko aplikazio lehenetsi gisa?" "Ez du behar baimenik" "Deitzailearen IDrako eta spamerako aplikazio lehenetsia" "Deitzailearen IDrako eta spamerako aplikazioa" - "Jasotako deiak ikustea, spama eta dei automatizatuak blokeatzea, nahi ez dituzun zenbakiak zerrenda beltzean sartzea eta antzeko gauzak egitea ahalbidetzen dizuten aplikazioak" + + "%1$s ezarri nahi duzu deitzailearen IDrako eta spamerako aplikazio lehenetsi gisa?" "Ez du behar baimenik" "Uneko aplikazio lehenetsia" @@ -280,10 +282,8 @@ "Bat ere ez" "(Sistemaren aplikazio lehenetsia)" "Ez dago aplikaziorik" - - - - + "Hautatuta" + "Hautatuta - %1$s" "aplikazio-baimen bereziak" "Aplikazio-baimen bereziak" "Ez dago aplikazio-baimen berezirik" diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml index f630b17ea..5fc1c91d9 100644 --- a/res/values-fa/strings.xml +++ b/res/values-fa/strings.xml @@ -254,12 +254,14 @@ "مجوز نیاز نیست" "برنامه هدایت تماس پیش‌فرض" "برنامه هدایت تماس" - "برنامه‌هایی که امکان می‌دهند تماس‌ها را به شماره تلفن دیگری بازارسال کنید" + + "%1$s به‌عنوان برنامه هدایت تماس پیش‌فرض تنظیم شود؟" "مجوز نیاز نیست" "شناسه تماس‌گیرنده و برنامه هرزنامه پیش‌فرض" "شناسه تماس‌گیرنده و برنامه هرزنامه" - "برنامه‌هایی که امکان می‌دهند تماس‌های ورودی را تشخیص دهید، هرزنامه‌ها و تماس‌های تلفنی خودکار را مسدود کنید، شماره‌های ناخواسته را در فهرست سیاه قرار دهید، و نظایر این‌ها" + + "%1$s به‌عنوان شناسه تماس‌گیرنده و برنامه هرزنامه‌ پیش‌فرض تنظیم شود؟" "مجوز نیاز نیست" "برنامه پیش‌فرض کنونی" @@ -280,10 +282,8 @@ "هیچ‌کدام" "(پیش‌فرض سیستم)" "برنامه‌ای موجود نیست" - - - - + "انتخاب شد" + "انتخاب‌شده - %1$s" "دسترسی ویژه برنامه" "دسترسی ویژه برنامه" "دسترسی ویژه برنامه وجود ندارد" diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml index fb20db1c7..7f333cb7f 100644 --- a/res/values-fi/strings.xml +++ b/res/values-fi/strings.xml @@ -254,12 +254,14 @@ "Käyttöoikeuksia ei tarvita" "Soitonsiirron oletussovellus" "Soitonsiirtosovellus" - "Sovellukset, joiden avulla voit siirtää puheluita toiseen numeroon" + + "Asetetaanko %1$s soitonsiirron oletussovellukseksi?" "Käyttöoikeuksia ei tarvita" "Soittajan tunnus ja häiriköinti: oletussov." "Soittajan tunnus ja häirik." - "Sovellukset, joiden avulla voit esimerkiksi tunnistaa saapuvat puhelut, estää häirikkö- ja robottipuhelut ja lisätä ei-toivottuja numeroita mustalle listalle" + + "Asetetaanko %1$s soittajan tunnuksen ja häiriköinnin eston oletussovellukseksi?" "Käyttöoikeuksia ei tarvita" "Nykyinen oletus" @@ -280,10 +282,8 @@ "Ei mitään" "(Järjestelmän oletusarvo)" "Ei sovelluksia" - - - - + "Valittu" + "Valittu – %1$s" "sovellusten erikoiskäyttö" "Sovellusten erikoiskäyttö" "Ei sovellusten erikoiskäyttöä" diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml index adb70cc19..2cf38be9f 100644 --- a/res/values-fr-rCA/strings.xml +++ b/res/values-fr-rCA/strings.xml @@ -254,12 +254,14 @@ "Aucune autorisation nécessaire" "Appli redirect. appel par déf." "Appeler l\'appli. de redirection" - "Applications qui vous permettent de transférer des appels vers un autre numéro de téléphone" + + "Définir %1$s comme application par défaut pour la redirection des appels?" "Aucune autorisation nécessaire" "Appli défaut identifier et filtrer appelants" "Appli identif. et filtr. appels" - "Applications qui vous permettent d\'identifier les appels entrants, de bloquer les appels indésirables et automatisés, de placer les numéros indésirables sur une liste noire et d\'effectuer d\'autres actions similaires" + + "Définir %1$s comme application par défaut pour l\'identification et le filtrage des appelants?" "Aucune autorisation nécessaire" "Application par défaut actuelle" diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index fcd548945..bc355397d 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -254,12 +254,14 @@ "Aucune autorisation nécessaire" "Appli redir. d\'appels par déf." "Appli de redirection d\'appels" - "Applications qui vous permettent de transférer les appels vers un autre numéro de téléphone" + + "Définir %1$s comme votre application par défaut pour la redirection des appels ?" "Aucune autorisation nécessaire" "Appli numéro de l\'appelant et spam par défaut" "Appli numéro de l\'appelant et spam" - "Applications qui vous permettent d\'identifier les appels entrants, de bloquer le spam et les appels automatiques, de mettre sur liste noire les numéros indésirables et plus encore" + + "Définir %1$s comme votre application par défaut pour l\'affichage du numéro de l\'appelant et du spam ?" "Aucune autorisation nécessaire" "Appli par défaut actuelle" @@ -280,10 +282,8 @@ "Aucune" "(Application système par défaut)" "Aucune application" - - - - + "Sélectionnée" + "Sélectionnée – %1$s" "accès spécifique des applications" "Accès spécifique des applis" "Aucun accès spécif. des applis" diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml index d6b949fb6..7361d457e 100644 --- a/res/values-gl/strings.xml +++ b/res/values-gl/strings.xml @@ -254,12 +254,14 @@ "Non se necesita ningún permiso" "App desvío de chamadas predet." "App de redirección de chamadas" - "Aplicacións que che permiten desviar chamadas a outro número de teléfono" + + "Queres definir %1$s como a túa aplicación predeterminada de desvío de chamadas?" "Non se necesita ningún permiso" "App de filtro de chamadas e spam predefinida" "App ident. de chamadas e spam" - "Aplicacións que che permiten identificar as chamadas entrantes, bloquear o spam e as chamadas automatizadas, engadir os números non desexados á lista negra e realizar outras accións similares" + + "Queres definir %1$s como a túa aplicación predeterminada de identificación de chamadas e spam?" "Non se necesita ningún permiso" "App predeterminada actual" @@ -280,10 +282,8 @@ "Ningunha" "(Opción predeterminada do sistema)" "Non hai ningunha aplicación" - - - - + "Aplicación seleccionada" + "Aplicación seleccionada (%1$s)" "acceso especial das aplicacións" "Acceso especial das aplicacións" "Sen acceso especial das apps" diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml index 24b7b45c8..cfd3ef9ba 100644 --- a/res/values-gu/strings.xml +++ b/res/values-gu/strings.xml @@ -254,12 +254,14 @@ "કોઈ પરવાનગી જરૂરી નથી" "ડિફૉલ્ટ કૉલ રીડાયરેક્ટિંગ ઍપ" "કૉલ રીડાયરેક્ટ કરનારી ઍપ" - "ઍપ કે જે તમને બીજા ફોન નંબર પર કૉલ ફૉર્વર્ડ કરવાની મંજૂરી આપે છે" + + "%1$sને તમારી ડિફૉલ્ટ કૉલ રીડાયરેક્શન ઍપ તરીકે સેટ કરીએ?" "કોઈ પરવાનગી જરૂરી નથી" "ડિફૉલ્ટ કૉલર ID અને સ્પામ ઍપ" "કૉલર ID અને સ્પામ ઍપ" - "ઍપ કે જે તમને ઇનકમિંગ કૉલ ઓળખવાની, સ્પામ અને રોબો કૉલને બ્લૉક કરવાની, અનિચ્છિત નંબરોને બ્લૅકલિસ્ટ કરવાની અને આવાં બીજાં કાર્યો કરવાની મંજૂરી આપે છે" + + "%1$sને તમારી ડિફૉલ્ટ કૉલર ID અને સ્પામ ઍપ તરીકે સેટ કરીએ?" "કોઈ પરવાનગી જરૂરી નથી" "હાલની ડિફૉલ્ટ" @@ -280,10 +282,8 @@ "કોઈ નહીં" "(સિસ્ટમ ડિફૉલ્ટ)" "કોઈ ઍપ નથી" - - - - + "પસંદ કરેલ" + "પસંદ કરેલ - %1$s" "વિશેષ ઍપનો ઍક્સેસ" "વિશેષ ઍપનો ઍક્સેસ" "કોઈ વિશેષ ઍપનો ઍક્સેસ નથી" diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml index e290e0f36..b29df6c49 100644 --- a/res/values-hi/strings.xml +++ b/res/values-hi/strings.xml @@ -254,12 +254,14 @@ "अनुमति की ज़रूरत नहीं है" "कॉल रीडायरेक्ट का डिफ़ॉल्ट ऐप" "कॉल रीडायरेक्ट करने वाला ऐप" - "ऐसे ऐप्लिकेशन जो आपको कॉल दूसरे फ़ोन नंबर पर भेजने की सुविधा देते हैं" + + "क्या आप %1$s को अपने डिफ़ॉल्ट कॉल रीडायरेक्शन ऐप्लिकेशन के तौर पर सेट करना चाहते हैं?" "अनुमति की ज़रूरत नहीं है" "डिफ़ॉल्ट कॉल आईडी और स्पैम ऐप्लिकेशन" "कॉल आईडी और स्पैम ऐप्लिकेशन" - "ऐप्लिकेशन से आप इनकमिंग कॉल पहचान सकते हैं, स्पैम और रोबोकॉल ब्लॉक कर सकते हैं, अनचाहे नंबर ब्लैकलिस्ट जैसी और भी चीज़ें कर सकते हैं" + + "क्या %1$s को अपना डिफ़ॉल्ट कॉलर आईडी और स्पैम आईडी के तौर पर सेट करना चाहते हैं?" "अनुमति की ज़रूरत नहीं है" "मौजूदा डिफ़ॉल्ट" @@ -280,10 +282,8 @@ "कोई नहीं" "(सिस्टम डिफ़ॉल्ट)" "कोई ऐप्लिकेशन नहीं" - - - - + "चुना हुआ" + "%1$s - चुना गया" "ऐप्लिकेशन को खास अनुमति" "ऐप्लिकेशन को खास अनुमति" "ऐप्लिकेशन को खास अनुमति नहीं" diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml index a37028ea7..67df37185 100644 --- a/res/values-hr/strings.xml +++ b/res/values-hr/strings.xml @@ -261,12 +261,14 @@ "Nije potrebno nijedno dopuštenje" "Zadana apl. za preusmj. poziva" "Apl. za preusmjeravanje poziva" - "Aplikacije koje vam omogućuju prosljeđivanje poziva na neki drugi telefonski broj" + + "Želite li postaviti aplikaciju %1$s kao zadanu aplikaciju za preusmjeravanje poziva?" "Nije potrebno nijedno dopuštenje" "ID poziv. i neželj. pozivi" "Apl. za ID pozivatelja/spam" - "Aplikacije koje vam omogućuju identifikaciju dolaznih poziva, blokiranje neželjenih i automatiziranih poziva, izradu popisa nedopuštenih brojeva i drugo" + + "Želite li postaviti aplikaciju %1$s kao svoju zadanu aplikaciju za ID pozivatelja i neželjene pozive?" "Nije potrebno nijedno dopuštenje" "Trenutačna zadana" diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml index 2165278f0..855d76b93 100644 --- a/res/values-hu/strings.xml +++ b/res/values-hu/strings.xml @@ -254,12 +254,14 @@ "Nincs szükség engedélyre" "Alapértelmezett hívásátirányító" "Hívásátirányító alkalmazás" - "Alkalmazások, amelyek lehetővé teszik a hívások átirányítását másik telefonszámra" + + "Beállítja a(z) %1$s alkalmazást alapértelmezett hívásátirányító alkalmazásként?" "Nincs szükség engedélyre" "Alapértelmezett hívóazonosító és spamszűrő" "Hívóazonosító és spamszűrő" - "Alkalmazások, amelyek lehetővé teszik a bejövő hívások azonosítását, a spam jellegű tartalmak és a robothívások letiltását, telefonszámok tiltólistára tételét stb." + + "Beállítja a(z) %1$s alkalmazást alapértelmezett hívóazonosító és spamszűrő alkalmazásként?" "Nincs szükség engedélyre" "Aktuális alapérték" @@ -280,10 +282,8 @@ "Nincs" "(Alapértelmezett)" "Nincs alkalmazás" - - - - + "Kiválasztva" + "Kiválasztva – %1$s" "különleges alkalmazás-hozzáférés" "Különleges alkalmazás-hozzáférés" "Nincs különleges hozzáférés" diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml index 24369355f..b4283104a 100644 --- a/res/values-hy/strings.xml +++ b/res/values-hy/strings.xml @@ -59,7 +59,7 @@ "Հավելվածներ չկան" "Տեղորոշման կարգավորումներ" "Այս սարքի տեղորոշման ծառայությունները տրամադրում է %1$s հավելվածը: Տեղադրության ցուցադրման կարգավորումները կարող եք փոխել տեղորոշման կարգավորումներից:" - "Եթե չտրամադրեք այս թույլտվությունը, ձեր սարքի հիմնական գործառույթները հնարավոր է պատշաճ չաշխատեն:" + "Եթե այս թույլտվությունը մերժեք, ձեր սարքի հիմնական գործառույթները հնարավոր է պատշաճ չաշխատեն:" "Կանոնների համաձայն" "Հասանելիությունը ֆոնային ռեժիմում անջատած է կանոնի համաձայն" "Հասանելիությունը ֆոնային ռեժիմում միացված է կանոնի համաձայն" @@ -120,7 +120,7 @@ %s հավելված "Դիտել բոլորը կառավարման վահանակում" - "Զտված է ըստ՝ %1$s" + "Զտիչ՝ %1$s" "Տեսնել բոլորը կառավարման վահանակում" "Զտիչ" "Զտել ըստ թույլտվությունների" @@ -254,12 +254,14 @@ "Թույլտվություններ հարկավոր չեն" "Զանգի վերահասցեավորման կանխադրված հավելված" "Զանգի վերահասցեավորման հավելված" - "Հավելվածներ, որոնք թույլ են տալիս վերահասցեավորել զանգերն այլ հեռախոսահամարի վրա" + + "Նշե՞լ %1$s հավելվածը որպես զանգերի վերահասցեավորման կանխադրված հավելված" "Թույլտվություններ հարկավոր չեն" "Համարների և սպամի որոշման կանխադրված հավելված" "Համարի/սպամի որոշման հավելված" - "Հավելվածներ, որոնք թույլ են տալիս ճանաչել հեռախոսահամարները, արգելափակել սպամն ու ավտոմատ զանգերը, սև ցուցակ գցել անցանկալի համարները և այլն" + + "Ընտրե՞լ %1$s հավելվածը որպես համարների ավտոմատ որոշման և սպամից պաշտպանվելու կանխադված հավելված" "Թույլտվություններ հարկավոր չեն" "Օգտագործվում է ըստ կանխադրման" @@ -280,10 +282,8 @@ "Չկա" "(Համակարգի կանխադրված հավելված)" "Հավելվածներ չկան" - - - - + "Ընտրված է" + "Ընտրված է – %1$s" "հատուկ հասանելիություն հավելվածների համար" "Հատուկ հասանելիություն" "Հատուկ հասանելիություն չկա" diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml index ca3d21f26..0d27ce76e 100644 --- a/res/values-in/strings.xml +++ b/res/values-in/strings.xml @@ -254,12 +254,14 @@ "Tidak ada izin yang diperlukan" "Apl pengalih panggilan default" "Aplikasi pengalihan panggilan" - "Aplikasi yang memungkinkan Anda meneruskan panggilan ke nomor telepon lain" + + "Tetapkan %1$s sebagai aplikasi pengalihan panggilan default Anda?" "Tidak ada izin yang diperlukan" "Aplikasi nomor penelepon & spam default" "Apl nomor penelepon & spam" - "Aplikasi yang memungkinkan Anda mengidentifikasi panggilan masuk, memblokir spam dan robocall, memasukkan nomor ke daftar nomor tak diinginkan, dan sebagainya" + + "Tetapkan %1$s sebagai aplikasi nomor penelepon & spam default Anda?" "Tidak ada izin yang diperlukan" "Default saat ini" diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml index f0d17101e..cfde345d3 100644 --- a/res/values-is/strings.xml +++ b/res/values-is/strings.xml @@ -254,12 +254,14 @@ "Engra heimilda krafist" "Sjálfg. forrit frams. símtala" "Símtalsflutningaforrit" - "Forrit sem leyfa þér að framsenda símtöl í annað símanúmer" + + "Viltu gera %1$s að sjálfgefnu forriti fyrir framsendingu símtala?" "Engra heimilda krafist" "Sjálfg. forrit númerabirtingar og ruslsímtala" "Forrit númerab. og ruslsímtala" - "Forrit sem gera þér kleift að sjá hver er að hringja, loka fyrir símtöl úr ruslnúmerum og sjálfvirk símtöl, setja óæskileg símanúmer á bannlista og svo framvegis" + + "Velja %1$s sem sjálfgefið forrit fyrir númerabirtingu og ruslpóst?" "Engra heimilda krafist" "Núverandi sjálfgefið forrit" diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml index 5539f4242..ec4532a7b 100644 --- a/res/values-it/strings.xml +++ b/res/values-it/strings.xml @@ -254,12 +254,14 @@ "Nessuna autorizzazione necessaria" "App reindirizz. chiamate pred." "App reindirizzamento chiamate" - "App che ti permettono di inoltrare le chiamate a un altro numero di telefono" + + "Impostare %1$s come app reindirizzamento chiamate predefinita?" "Nessuna autorizzazione necessaria" "App ID chiamante e spam" "App ID chiamante e spam" - "App che ti permettono di identificare le chiamate in arrivo, bloccare lo spam e le chiamate preregistrate, inserire nella lista nera i numeri indesiderati e così via" + + "Impostare %1$s come app ID chiamante e spam?" "Nessuna autorizzazione necessaria" "Valore predefinito attuale" diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml index 92e744a95..39766a153 100644 --- a/res/values-iw/strings.xml +++ b/res/values-iw/strings.xml @@ -268,12 +268,14 @@ "אין צורך בהרשאות" "אפליקציית ברירת מחדל להפניית שיחות" "אפליקציה להפניית שיחות" - "אפליקציות שמאפשרות לך להעביר שיחות אל מספר טלפון אחר" + + "להגדיר את %1$s כאפליקציית ברירת המחדל להפניית שיחות?" "אין צורך בהרשאות" "אפליקציית ברירת מחדל לשיחה מזוהה וחסימת ספאם" "אפליקציית שיחה מזוהה וחסימת ספאם" - "אפליקציות שמאפשרות לך לזהות שיחות נכנסות, לחסום ספאם ושיחות אוטומטיות, להעביר מספרים לא רצויים לרשימה השחורה וכן הלאה" + + "להגדיר את %1$s כאפליקציית ברירת המחדל לשיחות מזוהות וחסימת ספאם?" "אין צורך בהרשאות" "ברירת המחדל הנוכחית" diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml index 1c889bd26..69240d063 100644 --- a/res/values-ja/strings.xml +++ b/res/values-ja/strings.xml @@ -254,12 +254,14 @@ "必要な権限がありません" "デフォルトの通話転送アプリ" "通話転送アプリ" - "通話を別の電話番号に転送できるアプリです" + + "%1$s をデフォルトの通話転送アプリとして設定しますか?" "必要な権限がありません" "デフォルトの発信者番号 / 迷惑電話アプリ" "発信者番号 / 迷惑電話アプリ" - "着信の識別、迷惑電話やロボコールのブロック、不要な電話番号のブラックリストの作成などを行えるアプリです" + + "%1$s をデフォルトの発信者番号 / 迷惑電話アプリとして設定しますか?" "必要な権限がありません" "現在のデフォルト" @@ -280,10 +282,8 @@ "なし" "(システムのデフォルト)" "アプリなし" - - - - + "選択済み" + "選択済み - %1$s" "特別なアプリアクセス" "特別なアプリアクセス" "特別なアプリアクセスなし" diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml index 8308876d7..21cf1c737 100644 --- a/res/values-ka/strings.xml +++ b/res/values-ka/strings.xml @@ -254,12 +254,14 @@ "ნებართვები არ არის საჭირო" "ზარის გადამისამ. ნაგულისხ. აპი" "ზარების გადამისამართების აპი" - "აპები, რომლებიც საშუალებას გაძლევთ, გადაამისამართოთ ზარები ტელეფონის სხვა ნომერზე" + + "გახდეს %1$s თქვენი ნაგულისხმევი ზარების გადამისამართების აპი?" "ნებართვები არ არის საჭირო" "ნაგულისხმევი აბონენტის ID და სპამის აპი" "აბონენტის ID და სპამის აპი" - "აპები, რომლებიც საშუალებას გაძლევთ, ამოიცნოთ შემომავალი ზარები, დაბლოკოთ სპამი და ავტომატიზირებული ზარები, შავ სიაში შეიყვანოთ არასასურველი ნომრები და ა.შ." + + "გახდეს %1$s თქვენი ნაგულისხმევი აბონენტის ID და სპამის აპი?" "ნებართვები არ არის საჭირო" "ამჟამინდელი ნაგულისხმევი" diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml index fb36079b5..98df1fc8f 100644 --- a/res/values-kk/strings.xml +++ b/res/values-kk/strings.xml @@ -254,12 +254,14 @@ "Ешқандай рұқсат қажет емес." "Қоңыраулардың бағытын ауыстыратын әдепкі қолданба" "Қоңырау бағытын ауыстыру" - "Қоңырауларды басқа телефон нөміріне бағыттауға мүмкіндік беретін қолданбалар" + + "%1$s қоңыраулар бағытын ауыстыратын әдепкі қолданба болып орнатылсын ба?" "Ешқандай рұқсат қажет емес." "Әдепкі нөмірді автоматты анықтау, спам анықтау қолданбасы" "Нөмірді автоматты анықтау қызметі, спамды анықтау қолданбасы" - "Кіріс қоңырауларды анықтауға, спамды және автоматты қоңырауларды бөгеуге, қалаусыз нөмірлерді қара тізімге енгізуге, т.б. мүмкіндік беретін қолданбалар" + + "%1$s нөмірді автоматты анықтау қызметі мен спам анықтау қолданбасы болып орнатылсын ба?" "Ешқандай рұқсат қажет емес." "Ағымдағы әдепкі қолданба" @@ -280,10 +282,8 @@ "Жоқ" "(жүйенің әдепкі қолданбасы)" "Қолданбалар жоқ" - - - - + "Таңдалды" + "Таңдалды – %1$s" "арнайы қолданба рұқсаты" "Арнайы кіру" "Арнайы кіру мүмкіндігі жоқ" diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml index 7e9ec90d2..6b8a6c7ba 100644 --- a/res/values-km/strings.xml +++ b/res/values-km/strings.xml @@ -254,12 +254,14 @@ "មិន​ត្រូវការការអនុញ្ញាត​ទេ" "កម្មវិធី​បញ្ជូនបន្ត​​ការហៅទូរសព្ទលំនាំដើម" "កម្មវិធី​បញ្ជូនបន្ត​ការហៅទូរសព្ទ" - "កម្មវិធី​ដែលអនុញ្ញាតឱ្យអ្នក​បញ្ជូនបន្ត​ការហៅទូរសព្ទទៅ​លេខទូរសព្ទផ្សេងទៀត" + + "កំណត់ %1$s ជាកម្មវិធីបញ្ជូន​បន្តការហៅ​ទូរសព្ទ​លំនាំដើម​របស់អ្នក?" "មិន​ត្រូវការការអនុញ្ញាត​ទេ" "កម្មវិធី​សារ​ឥត​បាន​ការ និង​អត្តសញ្ញាណអ្នកហៅទូរសព្ទលំនាំដើម" "កម្មវិធី​សារ​ឥត​បាន​ការ និង​អត្តសញ្ញាណអ្នកហៅទូរសព្ទ" - "កម្មវិធី​ដែល​អនុញ្ញាត​ឱ្យអ្នក​សម្គាល់​ការហៅចូល ទប់ស្កាត់​សារឥតបានការ និងការ​ហៅ​ទូរសព្ទ​ដោយស្វ័យប្រវត្តិ ដាក់​លេខទូរសព្ទដែលមិនចង់បានចូលក្នុងបញ្ជីខ្មៅ និងធ្វើអ្វីៗជាច្រើនទៀត" + + "កំណត់​ %1$s ជាកម្មវិធីសារឥតបាន​ការ និង​​អត្តសញ្ញាណអ្នកហៅទូរសព្ទលំនាំដើមរបស់​អ្នក?" "មិន​ត្រូវការការអនុញ្ញាត​ទេ" "លំនាំដើម​បច្ចុប្បន្ន" @@ -280,10 +282,8 @@ "គ្មាន" "(លំនាំដើមប្រព័ន្ធ)" "គ្មានកម្មវិធី​ទេ​" - - - - + "បានជ្រើសរើស" + "បានជ្រើសរើស - %1$s" "ការចូលប្រើកម្មវិធីពិសេស" "ការចូលប្រើកម្មវិធីពិសេស" "គ្មានការចូលប្រើ​កម្មវិធី​ពិសេសទេ" diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml index b785d4aac..e32097a80 100644 --- a/res/values-kn/strings.xml +++ b/res/values-kn/strings.xml @@ -254,12 +254,14 @@ "ಯಾವುದೇ ಅನುಮತಿಗಳ ಅಗತ್ಯವಿಲ್ಲ" "ಡೀಫಾಲ್ಟ್ ಕರೆ ಮರುನಿರ್ದೇಶನ ಆ್ಯಪ್" "ಕರೆ ಮರುನಿರ್ದೇಶನ ಆ್ಯಪ್" - "ಬೇರೊಂದು ಫೋನ್ ಸಂಖ್ಯೆಗೆ ಕರೆಗಳನ್ನು ಫಾರ್ವರ್ಡ್ ಮಾಡಲು ನಿಮಗೆ ಅನುಮತಿಸುವ ಆ್ಯಪ್‌ಗಳು" + + "%1$s ಆ್ಯಪ್ ಅನ್ನು ನಿಮ್ಮ ಡೀಫಾಲ್ಟ್ ಕರೆ ಮರುನಿರ್ದೇಶನ ಆ್ಯಪ್ ಆಗಿ ಹೊಂದಿಸುವುದೇ?" "ಯಾವುದೇ ಅನುಮತಿಗಳ ಅಗತ್ಯವಿಲ್ಲ" "ಡೀಫಾಲ್ಟ್ ಕರೆ ಮಾಡುವವರ ID ಮತ್ತು ಸ್ಪ್ಯಾಮ್ ಆ್ಯಪ್" "ಕರೆಮಾಡುವವರ ID & ಸ್ಪ್ಯಾಮ್ ಆ್ಯಪ್" - "ಒಳಬರುವ ಕರೆಗಳನ್ನು ಗುರುತಿಸಲು. ಸ್ಪ್ಯಾಮ್ ಮತ್ತು ರೊಬೊಕಾಲ್‌ಗಳನ್ನು ನಿರ್ಬಂಧಿಸಲು, ಅನಗತ್ಯ ಸಂಖ್ಯೆಗಳನ್ನು ಬ್ಲ್ಯಾಕ್‌ಲಿಸ್ಟ್ ಮಾಡಲು ಮತ್ತು ಇತ್ಯಾದಿಗಳನ್ನು ಮಾಡಲು ನಿಮಗೆ ಅನುಮತಿಸುವ ಆ್ಯಪ್‌ಗಳು" + + "%1$s ಆ್ಯಪ್ ಅನ್ನು ನಿಮ್ಮ ಡೀಫಾಲ್ಟ್ ಕರೆಮಾಡುವವರ ID ಮತ್ತು ಸ್ಪ್ಯಾಮ್ ಆ್ಯಪ್ ಆಗಿ ಹೊಂದಿಸುವುದೇ?" "ಯಾವುದೇ ಅನುಮತಿಗಳ ಅಗತ್ಯವಿಲ್ಲ" "ಪ್ರಸ್ತುತ ಡೀಫಾಲ್ಟ್" @@ -280,10 +282,8 @@ "ಯಾವುದೂ ಬೇಡ" "(ಸಿಸ್ಟಂ ಡಿಫಾಲ್ಟ್)" "ಯಾವುದೇ ಆ್ಯಪ್‌ಗಳು ಇಲ್ಲ" - - - - + "ಆಯ್ಕೆಮಾಡಲಾಗಿದೆ" + "%1$s - ಆಯ್ಕೆಮಾಡಲಾಗಿದೆ" "ವಿಶೇಷ ಆ್ಯಪ್ ಪ್ರವೇಶ" "ಆ್ಯಪ್‌ಗೆ ವಿಶೇಷ ಪ್ರವೇಶ" "ಆ್ಯಪ್‌ಗೆ ವಿಶೇಷ ಪ್ರವೇಶವಿಲ್ಲ" diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml index fcbc622db..9d3c32817 100644 --- a/res/values-ko/strings.xml +++ b/res/values-ko/strings.xml @@ -254,12 +254,14 @@ "필요한 권한 없음" "기본 통화 리디렉션 앱" "통화 리디렉션 앱" - "다른 전화번호로 통화를 전달할 수 있게 해 주는 앱" + + "%1$s 앱을 기본 통화 리디렉션 앱으로 설정하시겠습니까?" "필요한 권한 없음" "기본 발신번호 표시 및 스팸 앱" "발신번호 표시 및 스팸 앱" - "수신 전화를 확인하고, 스팸 및 자동녹음전화를 차단하고, 원하지 않는 번호를 블랙리스트에 추가하는 등의 작업을 할 수 있는 앱" + + "%1$s 앱을 기본 발신번호 표시 및 스팸 앱으로 설정하시겠습니까?" "필요한 권한 없음" "현재 기본 앱" @@ -280,10 +282,8 @@ "없음" "(시스템 기본값)" "앱 없음" - - - - + "선택됨" + "선택됨 - %1$s" "특수 앱 액세스 권한" "특수 앱 액세스 권한" "특수 앱 액세스 권한 없음" diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml index a6d65c8b3..5826db980 100644 --- a/res/values-ky/strings.xml +++ b/res/values-ky/strings.xml @@ -254,12 +254,14 @@ "Уруксаттардын кереги жок" "Чалууну багыттоочу демейки колдонмо" "Чалууну багытточу колдонмо" - "Чалууларды башка телефон номерине багыттоого мүмкүнчүлүк берген колдонмолор" + + "%1$s колдонмосун демейки \"чалууларды багыттоо\" колдонмосу катары коёсузбу?" "Уруксаттардын кереги жок" "Демейки чалуучу идентификатору жана \"спам\" колдонмосу" "Чалуучунун идентификатору жана \"спам\" колдонмосу" - "Сизге чалып жаткан номерлерди аныктап, спамдарды жана автоматтык чалууларды бөгөттөп, керексиз номерлерди кара тизмеге киргизген колдонмолор" + + "%1$s колдонмосун чалуучунун демейки идентификатору жана \"спам\" колдонмосу катары коёсузбу?" "Уруксаттардын кереги жок" "Учурдагы демейки колдонмо" @@ -280,10 +282,8 @@ "Жок" "(Демейки тутум)" "Бир да колдонмо жок" - - - - + "Тандалды" + "Тандалды – %1$s" "колдонмонун атайын уруксаты" "Колдонмонун атайын уруксаты" "Колднмнун атайын уруксаты жок" diff --git a/res/values-lo/strings.xml b/res/values-lo/strings.xml index 2e1741fba..be75553a2 100644 --- a/res/values-lo/strings.xml +++ b/res/values-lo/strings.xml @@ -254,12 +254,14 @@ "ບໍ່ຈຳເປັນຕ້ອງມີສິດອະນຸຍາດ" "ແອັບການປ່ຽນເສັ້ນທາງການໂທເລີ່ມຕົ້ນ" "ແອັບການປ່ຽນເສັ້ນທາງສາຍ" - "ແອັບທີ່ອະນຸຍາດໃຫ້ທ່ານໂອນສາຍໄປໃຫ້ເບີໂທລະສັບອື່ນ" + + "ຕັ້ງ %1$s ເປັນແອັບປ່ຽນເສັ້ນທາງການໂທເລີ່ມຕົ້ນຂອງທ່ານບໍ?" "ບໍ່ຈຳເປັນຕ້ອງມີສິດອະນຸຍາດ" "ໝາຍເລກຜູ້ໂທ ແລະ ແອັບສະແປມເລີ່ມຕົ້ນ" "ໝາຍເລກຜູ້ໂທ ແລະ ແອັບສະແປມ" - "ແອັບທີ່ອະນຸຍາດໃຫ້ທ່ານລະບຸຕົວຕົນສາຍທີ່ໂທເຂົ້າມາ, ບລັອກສະແປມ ແລະ ການໂທອັດຕະໂນມັດ, ສ້າງບັນຊີດຳເບີໂທທີ່ບໍ່ຕ້ອງການ ແລະ ອື່ນໆ" + + "ຕັ້ງ %1$s ເປັນໝາຍເລກຜູ້ໂທເລີ່ມຕົ້ນ ແລະ ແອັບສະແປມເລີ່ມຕົ້ນຂອງທ່ານບໍ?" "ບໍ່ຈຳເປັນຕ້ອງມີສິດອະນຸຍາດ" "ຄ່າເລີ່ມຕົ້ນປັດຈຸບັນ" diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml index 5aa533fa4..cdcdcdf69 100644 --- a/res/values-lt/strings.xml +++ b/res/values-lt/strings.xml @@ -268,12 +268,14 @@ "Nereikia jokių leidimų" "Numatyt. skamb. peradr. progr." "Skambučių peradresav. programa" - "Programos, leidžiančios peradresuoti skambučius kitu telefono numeriu" + + "Nustatyti „%1$s“ kaip numatytąją skambučių peradresavimo programą?" "Nereikia jokių leidimų" "Numatytoji skambintojo ID ir šlamšto programa" "Skambint. ID ir šlamšto progr." - "Programos, leidžiančios identifikuoti gaunamuosius skambučius, blokuoti šlamštą ir automatinius skambučius, įtraukti į juodąjį sąrašą nepageidaujamus numerius ir pan." + + "Nustatyti „%1$s“ kaip numatytąją skambintojo ID ir šlamšto programą?" "Nereikia jokių leidimų" "Dabartinė numatytoji" @@ -294,10 +296,8 @@ "Nėra" "(Sistemos numatytoji programa)" "Nėra programų" - - - - + "Pasirinkta" + "Pasirinkta: %1$s" "speciali prieiga prie programų" "Speciali prieiga prie programų" "Nėra spec. prieig. prie progr." diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml index 4af10849e..a210706f7 100644 --- a/res/values-lv/strings.xml +++ b/res/values-lv/strings.xml @@ -261,12 +261,14 @@ "Atļaujas nav nepieciešamas" "Noklus. zvanu pāradr. lietotne" "Zvanu novirzīšanas lietotne" - "Lietotnes, kas ļauj jums pāradresēt zvanus uz citu tālruņa numuru" + + "Vai vēlaties iestatīt lietotni %1$s kā noklusējuma lietotni zvanu pāradresācijai?" "Atļaujas nav nepieciešamas" "Noklus. zvanītāja ID un nevēl. zvanu lietotne" "Zvanītāja ID un nevēl. zvaniem" - "Izmantojot šīs lietotnes, varat identificēt ienākošos zvanus, bloķēt nevēlamus zvanus un robotu zvanus, pievienot nevēlamus numurus melnajam sarakstam u.tml." + + "Vai vēlaties iestatīt %1$s kā noklusējuma lietotni zvanītāja ID rādīšanai un nevēlamu zvanu bloķēšanai?" "Atļaujas nav nepieciešamas" "Pašreizējais noklusējums" @@ -287,10 +289,8 @@ "Nav" "(Sistēmas noklusējums)" "Nav lietotņu" - - - - + "Atlasīta" + "Atlasīta — %1$s" "Īpaša lietotņu piekļuve" "Īpaša piekļuve lietotnēm" "Nav īpašas piekļuves lietotnēm" diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml index 3a5917a1c..b3f098cca 100644 --- a/res/values-mk/strings.xml +++ b/res/values-mk/strings.xml @@ -254,12 +254,14 @@ "Не се потреби дозволи" "Станд. аплик. за пренасочување" "Аплик. за пренасочување повици" - "Апликации што ви овозможуваат да проследувате повици до друг телефонски број" + + "Да се постави %1$s како ваша стандардна апликација за пренасочување?" "Не се потреби дозволи" "Стандардна апликација за ID на повикувач и спам" "Апл. за ID на повикувач и спам" - "Апликации што ви овозможуваат да ги идентификувате дојдовните повици, да блокирате спам и автоматизирани повици, да ги ставате непожелните броеви на црната листа итн." + + "Да се постави %1$s како ваша стандардна апликација за ID на повикувач и спам?" "Не се потреби дозволи" "Стандардна апликација сега" diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml index 7178b818d..2294378b9 100644 --- a/res/values-ml/strings.xml +++ b/res/values-ml/strings.xml @@ -254,12 +254,14 @@ "അനുമതികൾ ആവശ്യമില്ല" "ഡിഫോൾട്ട് കോൾ റീഡയറക്‌ടിംഗ് ആപ്പ്" "കോൾ റീഡയറക്‌ട് ചെയ്യുന്ന ആപ്പ്" - "മറ്റൊരു ഫോൺ നമ്പറിലേക്ക് നിങ്ങളുടെ കോളുകൾ കൈമാറാൻ അനുവദിക്കുന്ന ആപ്പുകൾ" + + "%1$s എന്നതിനെ നിങ്ങളുടെ ഡിഫോൾട്ട് കോൾ റീഡയറക്‌ട് ചെയ്യുന്ന ആപ്പായി സജ്ജീകരിക്കണോ?" "അനുമതികൾ ആവശ്യമില്ല" "ഡിഫോൾട്ട് കോളർ ഐഡിയും സ്‌പാം ആപ്പും" "കോളർ ഐഡിയും സ്‌പാം ആപ്പും" - "ഇൻകമിംഗ് കോളുകൾ തിരിച്ചറിയാനും സ്‌പാമും റോബോകോളും ബ്ലോക്ക് ചെയ്യാനും ആവശ്യമില്ലാത്ത നമ്പറുകൾ കരിമ്പട്ടികയിൽ ചേർക്കാനും മറ്റും അനുവദിക്കുന്ന ആപ്പുകൾ" + + "%1$s എന്നതിനെ നിങ്ങളുടെ ഡിഫോൾട്ട് കോളർ ഐഡി സ്‌പാം ആപ്പായി സജ്ജീകരിക്കണോ?" "അനുമതികൾ ആവശ്യമില്ല" "നിലവിലെ ഡിഫോൾട്ട്" diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml index 3d15b05de..178252348 100644 --- a/res/values-mn/strings.xml +++ b/res/values-mn/strings.xml @@ -254,12 +254,14 @@ "Ямар ч зөвшөөрөл шаардлагагүй" "Дуудлагыг дахин чиглүүлэх өгөгдмөл апп" "Дуудлагыг дахин чиглүүлэх апп" - "Танд дуудлагыг өөр утасны дугаар луу дамжуулах боломжийг олгодог аппууд" + + "%1$s-г дуудлагыг дахин чиглүүлэх өгөгдмөл аппаар тохируулах уу?" "Ямар ч зөвшөөрөл шаардлагагүй" "Дуудлага хийгчийн ID & спамын өгөгдмөл апп" "Дуудлага хийгчийн ID & спамын апп" - "Танд дуудлагыг хэнээс ирж буйг тодорхойлох, спам болон роботын дуудлагыг хориглох, хүсээгүй дугаараа хориглосон жагсаалтад оруулах болон бусад зүйлийг хийх боломжийг олгодог аппууд" + + "%1$s-г дуудлага хийгчийн ID болон спамын өгөгдмөл аппаар тохируулах уу?" "Ямар ч зөвшөөрөл шаардлагагүй" "Одоогийн өгөгдмөл апп" @@ -280,10 +282,8 @@ "Тохируулсан апп алга" "(Системийн өгөгдмөл)" "Апп алга" - - - - + "Сонгосон" + "Сонгосон - %1$s" "аппын тусгай хандалт" "Аппын тусгай хандалт" "Аппын тусгай хандалт алга" diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml index b8ded38ed..89e4b3486 100644 --- a/res/values-mr/strings.xml +++ b/res/values-mr/strings.xml @@ -37,7 +37,7 @@ "सर्व बंद केल्या" "कोणत्याही बंद केल्या नाहीत" "परवानगी द्या" - "प्रत्येक वेळी अनुमती द्या" + "सर्व वेळी अॅक्सेसची अनुमती द्या" "फक्त अ‍ॅप वापरत असताना अनुमती द्या" "सर्व वेळी अनुमती द्या" "अॅप्स" @@ -254,12 +254,14 @@ "परवानगीची गरज नाही" "डीफॉल्ट कॉल रीडिरेक्टिंग अ‍ॅप" "कॉल रीडिरेक्‍ट करणारे अ‍ॅप" - "तुम्हाला दुसर्‍या फोन नंबरवर कॉल फॉरवर्ड करू देणारी अ‍ॅप्स" + + "%1$s तुमचे डीफॉल्ट कॉल रीडिरेक्‍ट करण्याचे अ‍ॅप म्हणून सेट करायचे?" "परवानगीची गरज नाही" "डीफॉल्ट कॉलर आयडी आणि स्पॅम अ‍ॅप" "कॉलर आयडी आणि स्पॅम अ‍ॅप" - "तुम्हाला येणारे कॉल ओळखू देणारी, स्पॅम आणि रोबोकॉल ब्लॉक करू देणारी, नको असलेले नंबर ब्लॅकलिस्ट करू देणारी आणि बरेच काही करू देणारी अ‍ॅप्स" + + "%1$s तुमचे डीफॉल्ट कॉलर आयडी आणि स्पॅम अ‍ॅप म्हणून सेट करायचे?" "परवानगीची गरज नाही" "सद्य डीफॉल्ट" diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml index 0af1aadc0..4ac8cf080 100644 --- a/res/values-ms/strings.xml +++ b/res/values-ms/strings.xml @@ -254,12 +254,14 @@ "Kebenaran tidak diperlukan" "Apl pengubahhalaan pgln lalai" "Apl pengubahhalaan panggilan" - "Apl yang membenarkan anda memajukan panggilan ke nombor telefon lain" + + "Tetapkan %1$s sebagai apl pengubahhalaan panggilan lalai anda?" "Kebenaran tidak diperlukan" "ID pemanggil & apl spam lalai" "ID Pemanggil & apl spam" - "Apl yang membenarkan anda mengecam panggilan masuk, menyekat spam dan robopanggilan, menyenaraihitamkan nombor yang tidak dikehendaki, dsb." + + "Tetapkan %1$s sebagai ID pemanggil & apl spam lalai anda?" "Kebenaran tidak diperlukan" "Lalai semasa" @@ -280,10 +282,8 @@ "Tiada" "(Lalai sistem)" "Tiada apl" - - - - + "Dipilih" + "Dipilih - %1$s" "akses apl khas" "Akses apl khas" "Tiada akses apl khas" diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml index 93524fce6..622e27074 100644 --- a/res/values-my/strings.xml +++ b/res/values-my/strings.xml @@ -254,12 +254,14 @@ "ခွင့်ပြုချက် မလိုပါ" "မူရင်း ဖုန်းတစ်ဆင့်ခေါ် အက်ပ်" "ခေါ်ဆိုမှု တစ်ဆင့်ညွှန်အက်ပ်" - "ခေါ်ဆိုမှုများကို နောက်ဖုန်းနံပါတ်တစ်ခုသို့ ရှေ့ဆက်ပို့ရန် ခွင့်ပြုသော အက်ပ်များ" + + "%1$s ကို သင့်မူရင်း ဖုန်းတစ်ဆင့်ပြန်ခေါ်သည့် အက်ပ်အဖြစ် သတ်မှတ်လိုပါသလား။" "ခွင့်ပြုချက် မလိုပါ" "မူရင်း ခေါ်ဆိုသူ ID နှင့် စပမ်းအက်ပ်" "ခေါ်ဆိုသူ ID နှင့် စပမ်းအက်ပ်" - "အဝင်ခေါ်ဆိုမှုများ ခွဲခြားသတ်မှတ်ခြင်း၊ စပမ်းနှင့် အလိုအလျောက် ဖုန်းခေါ်ဆိုမှုစနစ်များ ပိတ်ဆို့ခြင်း၊ မလိုလားသော နံပါတ်များကို အမည်ပျက်စာရင်းသွင်းခြင်းနှင့် အခြားအရာများ ပြုလုပ်ခွင့်ပြုသော အက်ပ်များ" + + "%1$s ကို သင့်မူရင်း ခေါ်ဆိုသူ ID နှင့် စပမ်းအက်ပ်အဖြစ် သတ်မှတ်လိုပါသလား။" "ခွင့်ပြုချက် မလိုပါ" "လက်ရှိ မူရင်း" diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml index 7ed9eee61..d0b0203f5 100644 --- a/res/values-nb/strings.xml +++ b/res/values-nb/strings.xml @@ -254,12 +254,14 @@ "Ingen tillatelser er nødvendige" "Standardapp for viderekobling" "App for viderekobling av anrop" - "Apper som lar deg videresende anrop til et annet telefonnummer" + + "Vil du angi %1$s som standardapp for omdirigering av anrop?" "Ingen tillatelser er nødvendige" "Standardapp for anrops-ID og useriøse anrop" "Anrop-ID- + useriøse anropsapp" - "Apper som lar deg identifisere innkommende anrop, blokkere useriøse anrop og automatoppringing, svarteliste uønskede numre og så videre" + + "Vil du angi %1$s som standardapp for anrops-ID og håndtering av useriøse anrop?" "Ingen tillatelser er nødvendige" "Gjeldende standard" @@ -280,10 +282,8 @@ "Ingen" "(Systemstandard)" "Ingen apper" - - - - + "Valgt" + "Valgt – %1$s" "spesiell apptilgang" "Spesiell apptilgang" "Ingen spesiell apptilgang" diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml index 56402cbeb..5e115b3a4 100644 --- a/res/values-ne/strings.xml +++ b/res/values-ne/strings.xml @@ -254,12 +254,14 @@ "कुनै पनि अनुमति आवश्यक छैन" "कल रिडिरेक्ट गर्ने पूर्वनिर्धारित अनुप्रयोग" "कल रिडिरेक्ट गर्ने अनुप्रयोग" - "तपाईंलाई अर्को फोन नम्बरमा कल फर्वार्ड गर्न दिने अनुप्रयोगहरू" + + "तपाईंको कल रिडिरेक्ट गर्ने पूर्वनिर्धारित अनुप्रयोगका रूपमा %1$s सेट गर्ने हो?" "कुनै पनि अनुमति आवश्यक छैन" "कल गर्ने व्यक्तिको पूर्वनिर्धारित ID र स्प्याम अनुप्रयोग" "कल गर्ने व्यक्तिको ID रamp; स्प्यामसम्बन्धी अनुप्रयोग" - "तपाईंलाई आगामी कलको पहिचान गर्न, स्प्याम र रोबोकलमाथि रोक लगाउन, आफूले नचाहेका नम्बरहरूलाई कालो सूचीमा राख्न र यस्तै अन्य कार्य गर्न अनुमति दिने अनुप्रयोगहरू" + + "आफ्नो पूर्वनिर्धारित कल गर्ने व्यक्तिको ID र स्प्याम अनुप्रयोगका रूपमा %1$s सेट गर्ने हो?" "कुनै पनि अनुमति आवश्यक छैन" "हालको पूर्वनिर्धारित अनुप्रयोग" @@ -280,10 +282,8 @@ "कुनै पनि होइन" "(प्रणालीको पूर्वनिर्धारित अनुप्रयोग)" "कुनै पनि अनुप्रयोग छैन" - - - - + "चयन गरिएको" + "चयन गरिएको - %1$s" "अनुप्रयोगसम्बन्धी विशेष पहुँच" "अनुप्रयोगसम्बन्धी विशेष पहुँच" "एपसम्बन्धी कुनै विशेष पहुँच छैन" diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml index 4a9d364f7..f91bbbc10 100644 --- a/res/values-nl/strings.xml +++ b/res/values-nl/strings.xml @@ -254,12 +254,14 @@ "Geen rechten nodig" "Standaard-app doorschakelen" "App voor gesprekdoorschakeling" - "Apps waarmee je gesprekken kunt doorschakelen naar een ander telefoonnummer" + + "Wil je %1$s instellen als je standaard-app voor het doorschakelen van gesprekken?" "Geen rechten nodig" "Standaard-app voor beller-ID\'s en spam" "App voor beller-ID\'s en spam" - "Apps waarmee je inkomende gesprekken kunt identificeren, spam en robocalls kunt blokkeren, ongewenste nummers op de zwarte lijst kunt zetten, enzovoort" + + "%1$s instellen als standaard-app voor beller-ID\'s en spam?" "Geen rechten nodig" "Huidige standaard-app" diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml index 7fd0a57b0..c300e21c1 100644 --- a/res/values-or/strings.xml +++ b/res/values-or/strings.xml @@ -254,12 +254,14 @@ "କୌଣସି ଅନୁମତି ଆବଶ୍ୟକ ନାହିଁ" "ଡିଫଲ୍ଟ କଲ୍ ପୁନଃନିର୍ଦ୍ଦେଶିତ ଆପ୍‌" "କଲ୍ ପୁନଃନିର୍ଦ୍ଦେଶିତ କରା ଆପ୍" - "ଆପ୍ସ ଯାହା ଅନ୍ୟ ଫୋନ୍‌କୁ କଲ୍ଗୁଡ଼ିକୁ ଫର୍‍ୱାର୍ଡ କରିବାକୁ ଆପଣଙ୍କୁ ଅନୁମତି ଦିଏ" + + "%1$sକୁ ଆପଣଙ୍କ ଡିଫଲ୍ଟ କଲ୍ ପୁନଃନିର୍ଦ୍ଦେଶନା ଆପ୍ ଭାବରେ ସେଟ୍ କରିବେ କି?" "କୌଣସି ଅନୁମତି ଆବଶ୍ୟକ ନାହିଁ" "ଡିଫଲ୍ଟ କଲର୍ ID & ସ୍ପାମ୍ ଆପ୍" "କଲର୍ ID & ସ୍ପାମ୍ ଆପ୍" - "ଆପ୍ସ ଯାହା ଆପଣଙ୍କୁ ଇନ୍‌କମିଂ କଲ୍, ବ୍ଲକ୍ ସ୍ପାମ୍ ଏବଂ ରୋବୋକଲ୍, ବ୍ଲାକ୍‌ଲିଷ୍ଟରେ ଥିବା ଅନାବଶ୍ୟକ ନମ୍ବର ଏବଂ ଅନେକ କିଛି ଚିହ୍ନଟ କରିବା ପାଇଁ ଅନୁମତି ଦିଏ" + + "%1$sକୁ ଆପଣଙ୍କର ଡିଫଲ୍ଟ କଲର୍ ଆଇଡି & ସ୍ପାମ୍ ଆପ୍ ଭାବ୍ ସେଟ୍ କରିବେ କି?" "କୌଣସି ଅନୁମତି ଆବଶ୍ୟକ ନାହିଁ" "ସମ୍ପ୍ରତ୍ତି ଡିଫଲ୍ଟ" diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml index d3a59ff95..6053d85d3 100644 --- a/res/values-pa/strings.xml +++ b/res/values-pa/strings.xml @@ -254,12 +254,14 @@ "ਕਿਸੇ ਇਜਾਜ਼ਤ ਦੀ ਲੋੜ ਨਹੀਂ ਹੈ" "ਪੂਰਵ-ਨਿਰਧਾਰਤ ਕਾਲ ਬਦਲਣ ਵਾਲੀ ਐਪ" "ਕਾਲ ਬਦਲਣ ਵਾਲੀ ਐਪ" - "ਐਪਾਂ ਜੋ ਤੁਹਾਨੂੰ ਕਿਸੇ ਹੋਰ ਫ਼ੋਨ ਨੰਬਰ \'ਤੇ ਕਾਲਾਂ ਅੱਗੇ ਭੇਜਣ ਦਿੰਦੀਆਂ ਹਨ" + + "ਕੀ %1$s ਨੂੰ ਤੁਹਾਡੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਕਾਲ ਬਦਲਣ ਵਾਲੀ ਐਪ ਵਜੋਂ ਸੈੱਟ ਕਰਨਾ ਹੈ?" "ਕਿਸੇ ਇਜਾਜ਼ਤ ਦੀ ਲੋੜ ਨਹੀਂ ਹੈ" "ਪੂਰਵ-ਨਿਰਧਾਰਤ ਕਾਲਰ ਆਈ.ਡੀ. ਅਤੇ ਸਪੈਮ ਐਪ" "ਕਾਲਰ ਆਈ.ਡੀ. ਅਤੇ ਸਪੈਮ ਐਪ" - "ਐਪਾਂ ਜੋ ਤੁਹਾਨੂੰ ਆਉਣ ਵਾਲੀਆਂ ਕਾਲਾਂ ਦੀ ਪਛਾਣ ਕਰਨ, ਸਪੈਮ ਅਤੇ ਰੋਬੋਕਾਲਾਂ ਬਲਾਕ ਕਰਨ, ਅਣਚਾਹੇ ਨੰਬਰਾਂ ਨੂੰ ਬਲੈਕਲਿਸਟ ਕਰਨ ਅਤੇ ਹੋਰ ਬਹੁਤ ਚੀਜ਼ਾਂ ਕਰਨ ਦਿੰਦੀਆਂ ਹਨ" + + "ਕੀ %1$s ਨੂੰ ਤੁਹਾਡੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਕਾਲਰ ਆਈ.ਡੀ. ਅਤੇ ਸਪੈਮ ਐਪ ਵਜੋਂ ਸੈੱਟ ਕਰਨਾ ਹੈ?" "ਕਿਸੇ ਇਜਾਜ਼ਤ ਦੀ ਲੋੜ ਨਹੀਂ ਹੈ" "ਮੌਜੂਦਾ ਪੂਰਵ-ਨਿਰਧਾਰਤ" @@ -280,10 +282,8 @@ "ਕੋਈ ਨਹੀਂ" "(ਸਿਸਟਮ ਪੂਰਵ-ਨਿਰਧਾਰਤ)" "ਕੋਈ ਐਪਾਂ ਨਹੀਂ" - - - - + "ਚੁਣੀ ਗਈ" + "ਚੁਣੀ ਗਈ - %1$s" "ਖਾਸ ਐਪ ਪਹੁੰਚ" "ਵਿਸ਼ੇਸ਼ ਐਪ ਪਹੁੰਚ" "ਕੋਈ ਵਿਸ਼ੇਸ਼ ਐਪ ਪਹੁੰਚ ਨਹੀਂ" diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml index d79443795..fb6dd61e5 100644 --- a/res/values-pl/strings.xml +++ b/res/values-pl/strings.xml @@ -268,12 +268,14 @@ "Nie potrzebuje uprawnień" "Domyślna aplikacja do przekierowywania połączeń" "Aplikacja przekierowująca połączenia" - "Aplikacje umożliwiające przekazywanie połączeń pod inny numer telefonu" + + "Czy aplikacja %1$s ma być domyślną aplikacją do przekierowywania połączeń?" "Nie potrzebuje uprawnień" "Domyślna aplik. ident. rozmówców i spam" "Aplikacja do identyfikacji rozmówcy i spamu" - "Aplikacje umożliwiające m.in. identyfikowanie połączeń przychodzących, blokowanie spamu i automatycznych wiadomości telefonicznych, dodawanie numerów do czarnej listy" + + "Czy aplikacja %1$s ma być domyślną aplikacją do identyfikacji rozmówcy i spamu?" "Nie potrzebuje uprawnień" "Bieżąca aplikacja domyślna" @@ -294,10 +296,8 @@ "Brak" "(Domyślna aplikacja systemu)" "Brak aplikacji" - - - - + "Wybrana" + "Wybrana – %1$s" "aplikacje ze specjalnym dostępem" "Aplikacje ze specjalnym dostępem" "Brak aplikacji ze specjalnym dostępem" diff --git a/res/values-pt-rBR/strings.xml b/res/values-pt-rBR/strings.xml index 509dac561..0f3b906e9 100644 --- a/res/values-pt-rBR/strings.xml +++ b/res/values-pt-rBR/strings.xml @@ -254,12 +254,14 @@ "Nenhuma permissão necessária" "App padrão de redirecionamento de chamada" "App p/ redirecionar chamadas" - "Apps que permitem encaminhar chamadas para outro número de telefone" + + "Definir %1$s como app padrão de redirecionamento de chamada?" "Nenhuma permissão necessária" "App padrão de identificação de chamada e spam" "App de ID de chamada e spam" - "Apps que permitem identificar chamadas recebidas, bloquear spam, ligações automáticas e números indesejados e assim por diante" + + "Definir %1$s como app padrão de identificação de chamada e spam?" "Nenhuma permissão necessária" "Padrão atual" diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml index 40d0fd3e2..32563204a 100644 --- a/res/values-pt-rPT/strings.xml +++ b/res/values-pt-rPT/strings.xml @@ -254,12 +254,14 @@ "Não são necessárias autorizações." "Aplic. redirec. chamadas pred." "Aplic. de redirec. de chamadas" - "Aplicações que permitem encaminhar chamadas para outro número de telefone." + + "Pretende definir %1$s como a aplicação de redirecionamento de chamadas predefinida?" "Não são necessárias autorizações." "Aplicação identific. chamadas e spam predef." "App de ID de chamada e spam" - "Aplicações que permitem identificar as chamadas recebidas, bloquear spam e chamadas automáticas, adicionar números indesejados à lista negra, etc." + + "Pretende definir o %1$s como a aplicação de identificação de chamadas e spam predefinida?" "Não são necessárias autorizações." "Predefinição atual" diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml index 509dac561..0f3b906e9 100644 --- a/res/values-pt/strings.xml +++ b/res/values-pt/strings.xml @@ -254,12 +254,14 @@ "Nenhuma permissão necessária" "App padrão de redirecionamento de chamada" "App p/ redirecionar chamadas" - "Apps que permitem encaminhar chamadas para outro número de telefone" + + "Definir %1$s como app padrão de redirecionamento de chamada?" "Nenhuma permissão necessária" "App padrão de identificação de chamada e spam" "App de ID de chamada e spam" - "Apps que permitem identificar chamadas recebidas, bloquear spam, ligações automáticas e números indesejados e assim por diante" + + "Definir %1$s como app padrão de identificação de chamada e spam?" "Nenhuma permissão necessária" "Padrão atual" diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml index 73281bcd9..df60a8933 100644 --- a/res/values-ro/strings.xml +++ b/res/values-ro/strings.xml @@ -261,12 +261,14 @@ "Nu este nevoie de permisiuni" "Aplicație prestabilită pentru redirecționarea apelurilor" "Aplicația de redirecționare a apelurilor" - "Aplicațiile care vă permit să redirecționați apelurile către un alt număr de telefon" + + "Setați %1$s ca aplicație prestabilită pentru redirecționarea apelurilor?" "Nu este nevoie de permisiuni" "Aplicația prestabilită pentru ID-ul apelantului și spam" "Aplicația pentru ID-ul apelantului și spam" - "Aplicații care vă ajută să identificați apelurile primite, să blocați spamul și apelurile automate, să introduceți pe lista neagră numerele nedorite și multe altele" + + "Setați %1$s ca aplicație prestabilită pentru ID-ul apelantului și spam?" "Nu este nevoie de permisiuni" "Aplicația prestabilită actuală" @@ -287,10 +289,8 @@ "Niciuna" "(Valoare prestabilită de sistem)" "Nicio aplicație" - - - - + "Selectată" + "Selectat - %1$s" "acces special pentru aplicații" "Acces special pentru aplicații" "Niciun acces special pentru aplicații" diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index 97d2edba3..ec2d63d70 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -268,12 +268,14 @@ "Разрешения не требуются" "Переадресация (по умолчанию)" "Переадресация звонков" - "Приложения, которые позволяют перенаправлять звонки на другой номер телефона." + + "Сделать \"%1$s\" приложением для переадресации звонков по умолчанию?" "Разрешения не требуются" "АОН и защита от спама по умолчанию" "АОН и защита от спама" - "Приложения, которые позволяют определять номера, блокировать спам и автоматические звонки, заносить нежелательные номера в черный список и т. д." + + "Сделать \"%1$s\" приложением для автоматического определения номеров и защиты от спама по умолчанию?" "Разрешения не требуются" "Используется по умолчанию" @@ -294,10 +296,8 @@ "Нет" "(по умолчанию)" "Приложений нет" - - - - + "Выбрано" + "Выбрано: %1$s" "специальный доступ для приложений" "Спец. доступ для приложений" "Специальный доступ не настроен" diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml index aa9cd039b..64b2a918e 100644 --- a/res/values-si/strings.xml +++ b/res/values-si/strings.xml @@ -254,12 +254,14 @@ "අවසර අවශ්‍ය නැත" "පෙරනිමි ඇමතුම් ප්‍රතියොමු කිරීමේ යෙදුම" "ඇමතුම් ප්‍රතියොමු කිරීමේ යෙදුම" - "ඔබට ඇමතුම් වෙනත් දුරකථන අංකයක් වෙත යොමු කිරීමට ඉඩ සලසන යෙදුම්" + + "%1$s ඔබේ පෙරනිමි ඇමතුම් ප්‍රතියොමු කිරීමේ යෙදුම ලෙස සකසන්නේද?" "අවසර අවශ්‍ය නැත" "පෙරනිමි අමතන්නා හැඳුනුම් සහ අයාචිත යෙදුම" "අමතන්නා හැඳුනුම් සහ අයාචිත යෙදුම" - "ඔබට එන ඇමතුම් හඳුනා ගැනීමට, අයාචිත සහ රොබෝ ඇමතුම් අවහිර කිරීමට, අනවශ්‍ය අංක කළු ලැයිස්තු කිරීමට, සහ තවත් දේ සඳහා ඉඩ සලසන යෙදුම්" + + "%1$s ඔබේ පෙරනිමි අමතන්නා හැඳුනුම සහ අයාචිත යෙදුම ලෙස සකසන්නේද?" "අවසර අවශ්‍ය නැත" "වත්මන් පෙරනිමිය" diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml index 263e4e7c8..6a12c0fb1 100644 --- a/res/values-sk/strings.xml +++ b/res/values-sk/strings.xml @@ -268,12 +268,14 @@ "Nie sú potrebné žiadne povolenia" "Predvolená aplikácia na presmerovanie hovorov" "Aplikácia na presmer. hovorov" - "Aplikácie, ktoré vám umožňujú presmerovať hovory na iné telefónne číslo" + + "Chcete %1$s nastaviť ako predvolenú aplikáciu na presmerovanie hovorov?" "Nie sú potrebné žiadne povolenia" "Predvolená aplikácia na identifikáciu volajúcich a spamu" "Identifikácia volajúcich a spamu" - "Aplikácia, ktorá vám umožňuje identifikovať prichádzajúce hovory, blokovať spam a robotické hovory, pridávať nechcené čísla do zoznamu zakázaných čísel a pod." + + "Chcete aplikáciu %1$s nastaviť ako predvolenú aplikáciu na identifikáciu volajúcich a spamu?" "Nie sú potrebné žiadne povolenia" "Aktuálne predvolená" @@ -294,10 +296,8 @@ "Žiadna" "(Predvolená systémová)" "Žiadne aplikácie" - - - - + "Vybraná" + "Vybrané – %1$s" "špeciálny prístup aplikácií" "Špeciálny prístup aplikácií" "Žiadny špeciálny prístup aplikácií" diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml index 705b50bd6..eb2d50d9d 100644 --- a/res/values-sl/strings.xml +++ b/res/values-sl/strings.xml @@ -268,12 +268,14 @@ "Nobeno dovoljenje ni potrebno" "Privz. aplik. za preusm. klicev" "Aplikacija za preusm. klicev" - "Aplikacije, ki vam omogočajo posredovanje klicev na drugo telefonsko številko" + + "Želite aplikacijo %1$s nastaviti kot privzeto aplikacijo za preusmerjanje klicev?" "Nobeno dovoljenje ni potrebno" "Privz. apl. za ID klicatelja in nežel. klice" "ID klicatelja in neželeni klici" - "Aplikacije, ki vam omogočajo prepoznavo dohodnih klicev, blokiranje neželenih in avtomatiziranih klicev, uvrščanje številk na seznam blokiranih in drugo" + + "Želite aplikacijo %1$s nastaviti kot privzeto aplikacijo za ID-je klicateljev in neželene klice?" "Nobeno dovoljenje ni potrebno" "Trenutna privzeta nastavitev" diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml index 19a7e256a..6f86f24c3 100644 --- a/res/values-sq/strings.xml +++ b/res/values-sq/strings.xml @@ -254,12 +254,14 @@ "Nuk ka nevojë për asnjë autorizim" "Aplikacioni i parazgjedhur i ridrejtimit të telefonatave" "Aplikacioni i ridrejtimit të telefonatave" - "Aplikacione që të lejojnë t\'i transferosh telefonatat te një numër tjetër telefoni" + + "Dëshiron ta caktosh %1$s si aplikacionin e parazgjedhur për ridrejtimin e telefonatave?" "Nuk ka nevojë për asnjë autorizim" "Aplikacioni i parazgjedhur për ID-në dhe telefonuesit e bezdisshëm" "Aplikacioni për ID-në e telefonuesit dhe telefonuesit e bezdisshëm" - "Aplikacionet që të lejojnë të identifikosh telefonatat hyrëse, të bllokosh telefonatat e robotëve dhe të bezdisshme, të futësh numrat e padëshiruar në listën e zezë etj." + + "Dëshiron të caktosh %1$s si aplikacionin e parazgjedhur për ID-në e telefonuesit dhe telefonuesit e bezdisshëm?" "Nuk ka nevojë për asnjë autorizim" "Parazgjedhja aktuale" @@ -280,10 +282,8 @@ "Asnjë" "(Parazgjedhja e sistemit)" "Nuk ka aplikacione" - - - - + "Zgjedhur" + "Zgjedhur - %1$s" "qasje e veçantë e aplikacionit" "Qasje e veçantë aplikacioni" "Jo qasje e veçantë aplikacioni" diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml index 84956137b..6fddefab5 100644 --- a/res/values-sr/strings.xml +++ b/res/values-sr/strings.xml @@ -261,12 +261,14 @@ "Није потребна ниједна дозвола" "Подраз. апл. за преус. позива" "Апл. за преусмеравање позива" - "Апликације које вам омогућавају да прослеђујете позиве на други број телефона" + + "Желите ли да подесите %1$s као подразумевану апликацију за преусмеравање позива?" "Није потребна ниједна дозвола" "Подраз. апл. за ИД позив. и непож. поруке" "Апл. за ИД поз. и непож. поз." - "Апликације које вам омогућавају да идентификујете позиве, блокирате непожељне и аутоматизоване позиве, блокирате нежељене бројеве и друго" + + "Желите ли да подесите %1$s као подразумевану апликацију за ИД позиваоца и непожељне поруке?" "Није потребна ниједна дозвола" "Тренутно подразумевана" diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml index ea3d95bf7..8fda287ea 100644 --- a/res/values-sv/strings.xml +++ b/res/values-sv/strings.xml @@ -254,12 +254,14 @@ "Inga behörigheter krävs" "Standardapp för omdirigering" "Omdirigeringsapp för samtal" - "Appar som möjliggör vidarebefordran av samtal till andra telefonnummer" + + "Vill du ställa in %1$s som din standardapp för omdirigering av samtal?" "Inga behörigheter krävs" "Standardapp för nummerpresentatör och spam" "Spam- och nummerpresentatörapp" - "Appar som möjliggör identifiering av inkommande samtal, blockering av spam och robotsamtal, svartlistning av oönskade nummer och liknande" + + "Vill du ställa in %1$s som din standardapp för spam och nummerpresentatör?" "Inga behörigheter krävs" "Nuvarande standardapp" diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml index adfc41b00..86a394483 100644 --- a/res/values-sw/strings.xml +++ b/res/values-sw/strings.xml @@ -254,12 +254,14 @@ "Hakuna ruhusa zinazohitajika" "Programu chaguomsingi ya kuelekeza simu kwingine" "Programu ya kuelekeza simu" - "Programu zinazokuruhusu usambaze simu kwenye nambari nyingine ya simu" + + "Je, ungependa kuweka %1$s iwe programu yako chaguomsingi ya kuelekeza simu kwingine?" "Hakuna ruhusa zinazohitajika" "Kitambulisho chaguomsingi cha anayepiga na programu taka" "Programu ya kugua kitambulisho cha anayepiga na taka" - "Programu zinazokuruhusu utambue simu zinazoingia, kuzuia taka na simu zinazopigwa kiotomatiki, kuziondolea idhini nambari zisizohitajika na kadhalika." + + "Je, ungependa kuweka %1$s iwe programu chaguomsingi ya kukagua kitambulisho cha anayepiga na taka?" "Hakuna ruhusa zinazohitajika" "Chaguomsingi ya sasa" @@ -280,10 +282,8 @@ "Hakuna" "(Programu chaguomsingi ya mfumo)" "Hakuna programu" - - - - + "Umechagua" + "Umechagua - %1$s" "ufikiaji maalum wa programu" "Ufikiaji wa programu maalum" "Hamna kufikia programu maalum" diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml index 3fc2f3b0d..ddc0d36e2 100644 --- a/res/values-ta/strings.xml +++ b/res/values-ta/strings.xml @@ -210,8 +210,7 @@ 1 விநாடி "அனுமதிக்கான நினைவூட்டல்கள்" - - + "%s ஆப்ஸ் உங்கள் இருப்பிடத்தைப் பின்புலத்தில் பெற்றது" "எப்பொழுதும் உங்கள் இருப்பிடத்தை இந்த ஆப்ஸால் பயன்படுத்த இயலும். மாற்றத் தட்டவும்." "ஆப்ஸ் உபயோகத்தில் இருக்கும்போது மட்டும்" "எந்த அனுமதிகளும் வழங்கப்படவில்லை" @@ -255,12 +254,14 @@ "அனுமதிகள் தேவையில்லை" "இயல்பு அழைப்புதிருப்பும் ஆப்ஸ்" "அழைப்பைத் திருப்பிவிடும் ஆப்ஸ்" - "அழைப்புகளை வேறு மொபைல் எண்ணிற்குத் திருப்பிவிட அனுமதிக்கும் ஆப்ஸ்" + + "%1$sஐ அழைப்பைத் திசைதிருப்பும் இயல்பான ஆப்ஸாக அமைக்கவா?" "அனுமதிகள் தேவையில்லை" "இயல்பான அழைப்பாளர் ஐடி & ஸ்பேம் ஆப்ஸ்" "அழைப்பாளர் ஐடி & ஸ்பேம் ஆப்ஸ்" - "உங்களுக்கு வரும் அழைப்புகள், ஸ்பேம் மற்றும் ரோபோ அழைப்புகள் போன்றவற்றை அடையாளம் காணவும், தேவையில்லாத எண்களை மறுப்புப்பட்டியலில் சேர்க்கவும், மேலும் பலவற்றைச் செய்யவும் அனுமதிக்கும் ஆப்ஸ்" + + "%1$sஐ இயல்பான அழைப்பாளர் ஐடி & ஸ்பேம் ஆப்ஸாக அமைக்கவா?" "அனுமதிகள் தேவையில்லை" "தற்போதைய இயல்பான ஆப்ஸ்" diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml index 242d0f9a3..2e0ecc329 100644 --- a/res/values-te/strings.xml +++ b/res/values-te/strings.xml @@ -254,12 +254,14 @@ "అనుమతులు ఇవ్వనవసరం లేదు" "డిఫాల్ట్ కాల్ మళ్లింపు యాప్" "కాల్ మళ్లింపు యాప్" - "కాల్‍లను మరో ఫోన్ నంబర్‌కు ఫార్వర్డ్ చేయడానికి మిమ్మల్ని అనుమతించే యాప్‌లు" + + "%1$sను మీ డిఫాల్ట్ కాల్ మళ్లింపు యాప్‌గా సెట్ చేయాలా?" "అనుమతులు ఇవ్వనవసరం లేదు" "డిఫాల్ట్ కాలర్ ID & స్పామ్ యాప్" "కాలర్ ID & స్పామ్ యాప్" - "ఇన్‌కమింగ్ కాల్‌లను గుర్తించడానికి, స్పామ్ మరియు రోబో కాల్‌లను బ్లాక్ చేయడానికి, అలాగే వద్దనుకునే నంబర్‌లను బ్లాక్‌లిస్ట్ చేయడానికి, మరిన్నింటిని చేయడానికి మిమ్మల్ని అనుమతించే యాప్‌లు" + + "%1$sను మీ డిఫాల్ట్ కాలర్ ID & స్పామ్ యాప్‌గా సెట్ చేయాలా?" "అనుమతులు ఇవ్వనవసరం లేదు" "ప్రస్తుతం డిఫాల్ట్‌గా ఉన్నది" diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml index 8f04d3883..ad8bbf6b7 100644 --- a/res/values-th/strings.xml +++ b/res/values-th/strings.xml @@ -254,12 +254,14 @@ "ไม่ต้องใช้สิทธิ์" "แอปเปลี่ยนเส้นทางการโทรเริ่มต้น" "แอปเปลี่ยนเส้นทางสายเรียกเข้า" - "แอปที่ให้คุณโอนสายไปยังหมายเลขโทรศัพท์อื่น" + + "ตั้งค่า %1$s เป็นแอปเปลี่ยนเส้นทางการโทรเริ่มต้นไหม" "ไม่ต้องใช้สิทธิ์" "แอปเริ่มต้นสำหรับสกรีนหมายเลขผู้โทรและสแปม" "แอปสกรีนหมายเลขผู้โทรและสแปม" - "แอปที่ให้คุณระบุสายเรียกเข้า บล็อกสแปมและสายจากระบบตอบรับอัตโนมัติ รวมถึงขึ้นบัญชีดำหมายเลขที่ไม่พึงประสงค์ และอีกมากมาย" + + "ตั้งค่า %1$s เป็นแอปเริ่มต้นสำหรับสกรีนหมายเลขผู้โทรและสแปมไหม" "ไม่ต้องใช้สิทธิ์" "แอปเริ่มต้นปัจจุบัน" @@ -268,7 +270,7 @@ "แอปเริ่มต้น" "รับทราบ" "ตั้งค่าความเป็นส่วนตัว" - "มีหลายแอปกำลังใช้%sของคุณ" + "แอปที่กำลังใช้%sของคุณ" " " " และ " "การตั้งค่า" @@ -280,10 +282,8 @@ "ไม่มี" "(ค่าเริ่มต้นของระบบ)" "ไม่มีแอป" - - - - + "เลือกไว้" + "เลือกไว้ - %1$s" "สิทธิ์เข้าถึงพิเศษของแอป" "สิทธิ์เข้าถึงพิเศษของแอป" "ไม่มีสิทธิ์เข้าถึงพิเศษของแอป" diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml index 2c21c0818..982681dab 100644 --- a/res/values-tl/strings.xml +++ b/res/values-tl/strings.xml @@ -254,12 +254,14 @@ "Walang kailangang pahintulot" "Default call redirecting app" "App sa pag-redirect ng tawag" - "Mga app na nagbibigay-daan sa iyong magpasa ng mga tawag sa isa pang numero ng telepono" + + "Itakda ang %1$s bilang iyong default na app sa pag-redirect?" "Walang kailangang pahintulot" "Default na app para sa caller ID at spam" "App para sa caller ID at spam" - "Mga app na nagbibigay-daan sa iyong tukuyin ang mga papasok na tawag, i-block ang mga spam at robocall, i-blacklist ang mga hindi gustong numero, at higit pa" + + "Itakda ang %1$s bilang iyong default na caller ID at spam app?" "Walang kailangang pahintulot" "Kasalukuyang default" @@ -280,10 +282,8 @@ "Wala" "(Default ng system)" "Walang app" - - - - + "Napili" + "Pinili - %1$s" "Espesyal na access ng app" "Espesyal na app access" "Walang espesyal na app access" diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml index aa06a945e..ef40a56c9 100644 --- a/res/values-tr/strings.xml +++ b/res/values-tr/strings.xml @@ -254,12 +254,14 @@ "Herhangi bir izin gerekli değil" "Varsayılan arama yönlendirme uygulaması" "Arama yönlendirme uygulaması" - "Telefon aramalarını başka bir telefon numarasına yönlendirmenize olanak tanıyan uygulamalar" + + "%1$s, varsayılan arama yönlendirme uygulamanız olarak ayarlansın mı?" "Herhangi bir izin gerekli değil" "Varsayılan arayan kimliği ve spam uygulaması" "Arayan kimliği ve spam uygulaması" - "Gelen aramaları tanımlamanıza, spam ve otomatik çağrıları engellemenize, istenmeyen numaraları kara listeye almanıza ve benzer işlemler gerçekleştirmenize olanak tanıyan uygulamalar" + + "%1$s, varsayılan arayan kimliği ve spam uygulamanız olarak ayarlansın mı?" "Herhangi bir izin gerekli değil" "Mevcut varsayılan" @@ -280,10 +282,8 @@ "Yok" "(Sistem varsayılanı)" "Uygulama yok" - - - - + "Seçildi" + "Seçildi - %1$s" "özel uygulama erişimi" "Özel uygulama erişimi" "Özel uygulama erişimi yok" diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml index 45bfa7032..f25c9ba6d 100644 --- a/res/values-uk/strings.xml +++ b/res/values-uk/strings.xml @@ -124,7 +124,7 @@ %s додатка "Переглянути деталі на інформаційній панелі" - "Відфільтровано за параметром: %1$s" + "Відфільтровано за параметром \"%1$s\"" "Переглянути все на інформаційній панелі" "Фільтр" "Фільтрувати за дозволами" @@ -224,7 +224,7 @@ %s секунди "Нагадування про дозволи" - "Додаток %s отримав доступ до даних про місцезнаходження у фоновому режимі" + "Додаток %s визначив ваше місцезнаходження у фоновому режимі" "Цей додаток завжди має доступ до геоданих пристрою. Торкніться, щоб змінити це." "Лише коли додаток використовується" "Немає наданих дозволів" @@ -268,12 +268,14 @@ "Дозволи не потрібні" "Додаток для переспрямування викликів за умовчанням" "Додаток для переспрямування викликів" - "Додатки, у яких можна переадресовувати виклики на інший номер телефону" + + "Чи має %1$s використовуватись як додаток для переспрямування викликів за умовчанням?" "Дозволи не потрібні" "Автоматичний визначник номера й засіб від спаму за умовчанням" "Автоматичний визначник номера й засіб від спаму" - "Додатки, у яких можна визначати номери, з яких здійснюються вхідні дзвінки, блокувати спам і автоматичні виклики, вносити в чорний список небажані номери тощо" + + "Чи має %1$s використовуватись як автоматичний визначник номера й засіб від спаму за умовчанням?" "Дозволи не потрібні" "Поточний за умовчанням" @@ -294,10 +296,8 @@ "Немає" "(За умовчанням)" "Немає додатків" - - - - + "Вибрано" + "Вибрано: %1$s" "спеціальний доступ додатка" "Спеціальний доступ" "Немає спеціального доступу" diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml index c40c7731a..7515ade92 100644 --- a/res/values-ur/strings.xml +++ b/res/values-ur/strings.xml @@ -254,12 +254,14 @@ "کوئی اجازت درکار نہیں ہے" "کال ری ڈائریکٹنگ کی ڈیفالٹ ایپ" "کال ری ڈائریکٹ کرنے والی اپپ" - "وہ ایپس جو آپ کو کسی دوسرے فون نمبر پر کالز کو فارورڈ کرنے کی اجازت دیتی ہیں" + + "%1$s کو کال ری ڈائریکشن کی آپ کی ڈیفالٹ ایپ کے بطور سیٹ کریں؟" "کوئی اجازت درکار نہیں ہے" "‏کال کرنے والے کی ID اور اسپام کی ڈیفالٹ ایپ" "‏کال کرنے والے کی ID اور اسپام کی ایپ" - "وہ ایپس جو آپ کو موصول ہونے والی کالز کی شناخت کرنے، اسپام اور روبو کالز کو مسدود کرنے، غیر مطلوبہ نمبرز کو بلیک لسٹ کرنے اور مزيد بہت کچھ کرنے کی اجازت دیتی ہیں" + + "‏%1$s کو کال کرنے والے کی ID اور اسپام کی آپ کی ڈیفالٹ ایپ کے بطور سیٹ کریں؟" "کوئی اجازت درکار نہیں ہے" "موجودہ ڈیفالٹ" diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml index c3d3d7d17..1a3bd882a 100644 --- a/res/values-uz/strings.xml +++ b/res/values-uz/strings.xml @@ -254,12 +254,14 @@ "Hech qanday ruxsat zarur emas" "Asosiy chaqiruvlarni uzatish ilovasi" "Chaqiruvlarni uzatish ilovasi" - "Chaqiruvlarni boshqa telefon raqamiga uzatish ruxsatini beruvchi ilovalar" + + "%1$s asosiy chaqiruvlarni uzatish ilovasi sifatida sozlansinmi?" "Hech qanday ruxsat zarur emas" "Asosiy raqamni aniqlash va spam ilovasi" "Raqamni aniqlash va spam ilovasi" - "Kiruvchi chaqiruvlarni aniqlash, spam va avtomat chaqiruvlarni bloklash, keraksiz raqamlarni qora roʻyxatga olish ruxsatini beruvchi ilovalar" + + "%1$s asosiy raqamni aniqlash xizmati va spam sifatida sozlansinmi?" "Hech qanday ruxsat zarur emas" "Hozirda asosiy ilova" @@ -280,10 +282,8 @@ "Hech qanday" "(Birlamchi)" "Hech qanday ilova topilmadi" - - - - + "Tanlandi" + "Tanlandi – %1$s" "maxsus ilova ruxsatlari" "Maxsus ruxsatlar" "Maxsus ilova ruxsatlari yoʻq" diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml index 58d2408fe..7c3beb0ab 100644 --- a/res/values-vi/strings.xml +++ b/res/values-vi/strings.xml @@ -59,7 +59,7 @@ "Không có ứng dụng" "Cài đặt vị trí" "%1$s là nhà cung cấp dịch vụ vị trí cho thiết bị này. Bạn có thể sửa đổi quyền truy cập vào vị trí trong mục cài đặt vị trí." - "Nếu bạn từ chối quyền này, thì các tính năng cơ bản của thiết bị có thể không còn hoạt động như dự kiến." + "Nếu bạn từ chối quyền này thì các tính năng cơ bản của thiết bị có thể không còn hoạt động như dự kiến." "Thực thi theo chính sách" "Quyền truy cập khi ở nền sau đã tắt theo chính sách" "Quyền truy cập khi ở nền sau đã bật theo chính sách" @@ -254,12 +254,14 @@ "Không cần quyền" "Ứng dụng chuyển hướng cuộc gọi mặc định" "Ứng dụng chuyển hướng cuộc gọi" - "Các ứng dụng cho phép bạn chuyển tiếp cuộc gọi đến một số điện thoại khác" + + "Bạn muốn đặt %1$s làm ứng dụng chuyển hướng cuộc gọi mặc định?" "Không cần quyền" "Ứng dụng nhận dạng người gọi và chặn spam" "Ứng dụng chặn spam, số gọi đến" - "Các ứng dụng giúp bạn xác định cuộc gọi đến, chặn spam và cuộc gọi tự động, đưa các số không mong muốn vào danh sách cấm và nhiều tính năng khác" + + "Bạn muốn đặt %1$s làm ứng dụng chặn spam và số gọi đến mặc định?" "Không cần quyền" "Ứng dụng mặc định hiện tại" @@ -280,10 +282,8 @@ "Không có" "(Ứng dụng mặc định của hệ thống)" "Không có ứng dụng nào" - - - - + "Đã chọn" + "Đã chọn – %1$s" "quyền truy cập ứng dụng đặc biệt" "Quyền truy cập đặc biệt" "Không có quyền truy cập đặc biệt" diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml index c495bf0fd..18aab04b2 100644 --- a/res/values-zh-rCN/strings.xml +++ b/res/values-zh-rCN/strings.xml @@ -254,12 +254,14 @@ "无需任何权限" "默认来电转接应用" "来电转接应用" - "这类应用可让您将来电转接到其他电话号码" + + "要将%1$s设为您的默认来电转接应用吗?" "无需任何权限" "默认的来电显示和骚扰电话屏蔽应用" "来电显示和骚扰电话屏蔽应用" - "这类应用可让您识别来电、屏蔽骚扰电话和录音推销电话、将骚扰电话号码加入黑名单等" + + "要将%1$s设为您的默认来电显示和骚扰电话屏蔽应用吗?" "无需任何权限" "当前默认应用" @@ -280,10 +282,8 @@ "无" "(系统默认)" "没有应用" - - - - + "已选择" + "已选择 - %1$s" "特殊应用权限" "特殊应用权限" "没有特殊应用权限" diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml index 02066d136..7d8c68ba0 100644 --- a/res/values-zh-rHK/strings.xml +++ b/res/values-zh-rHK/strings.xml @@ -254,12 +254,14 @@ "無需任何權限" "預設通話重新導向應用程式" "通話重新導向應用程式" - "此類應用程式允許您將來電轉駁至其他手機號碼" + + "要將「%1$s」設為預設通話重新導向應用程式嗎?" "無需任何權限" "預設來電顯示與垃圾郵件應用程式" "來電顯示與垃圾郵件應用程式" - "此類應用程式允許您辨識來電、封鎖垃圾郵件和預錄電話、將騷擾電話號碼加入黑名單及執行其他動作" + + "要將「%1$s」設為預設來電顯示與垃圾郵件應用程式嗎?" "無需任何權限" "目前預設" @@ -280,10 +282,8 @@ "無" "(系統預設)" "沒有應用程式" - - - - + "已選取" + "已選取 - %1$s" "特別應用程式存取權" "特別應用程式權限" "沒有特別應用程式權限" diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml index 1c8a098d5..52761e16c 100644 --- a/res/values-zh-rTW/strings.xml +++ b/res/values-zh-rTW/strings.xml @@ -254,12 +254,14 @@ "無需任何權限" "預設的電話轉接應用程式" "來電轉接應用程式" - "這類應用程式可讓你將來電轉接到其他電話號碼" + + "要將「%1$s」設為預設的來電轉接應用程式嗎?" "無需任何權限" "預設的來電顯示與騷擾/廣告電話過濾應用程式" "來電顯示與騷擾/廣告電話過濾應用程式" - "這類應用程式可讓你辨識來電、封鎖騷擾/廣告電和自動語音電話、將不想接聽的電話號碼加入黑名單等等" + + "要將「%1$s」設為預設的來電顯示與騷擾/廣告電話過濾應用程式嗎?" "無需任何權限" "目前的預設應用程式" @@ -280,10 +282,8 @@ "無" "(系統預設)" "沒有可用的應用程式" - - - - + "已選取" + "已選取 - %1$s" "特殊應用程式存取權" "特殊應用程式存取權" "沒有特殊應用程式存取權" diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml index d66d37009..82e1e410f 100644 --- a/res/values-zu/strings.xml +++ b/res/values-zu/strings.xml @@ -254,12 +254,14 @@ "Azikho izimvume ezidingwayo" "Uhlelo lokusebenza lwekholi ezenzakalelayo lokuqondisa kabusha" "Uhlelo lokusebenza lokuqondisa kabusha ikholi" - "Izinhlelo zokusebenza ezikuvumela ukuthi udlulisele amakholi kwenye inombolo yefoni" + + "Setha i-%1$s njengohlelo lwakho lokusebenza oluzenzakalelayo lwekholi oluqondiswe kabusha?" "Azikho izimvume ezidingwayo" "Ubunikazi bekholi obuzenzakalelayo nohlelo lokusebenza logaxekile" "Ubunikazi bekholi nohlelo lokusebenza logaxekile" - "Izinhlelo zokusebenza ezikuvumela ukuthi ukhombe amakholi angenayo, uvimbele ugaxekile, uphinde wenze uhlu lokuvimbela ama-robocall wezinombolo ezingadingeki, njalo njalo" + + "Setha i-%1$s njengobunikazi bakho bekholi obuzenzakalelayo nohlelo lokusebenza logaxekile?" "Azikho izimvume ezidingwayo" "Okuzenzakalelayo kwamanje" @@ -280,10 +282,8 @@ "Lutho" "(Okuzenzakalelayo kwesistimu)" "Azikho izinhlelo zokusebenza" - - - - + "Ekhethiwe" + "Ekhethiwe - %1$s" "ukufinyelela kohlelo lokusebenza okukhethekile" "Ukungena kohlelo okukhethekile" "Akukho ukungena okukhethekile" -- GitLab From 5ce9fcba6c266b5b8401fedae52a9fc3a7a25726 Mon Sep 17 00:00:00 2001 From: Priyank Singh Date: Mon, 13 May 2019 10:58:03 -0700 Subject: [PATCH 636/701] Adding a fragment to launch the OngoingPrivacy dialog. Bug: 123355120 Test: Manual Change-Id: Ib19fc2d84a63ce25cbcdd5ca7df0bcaa9eae51f0 --- .../ui/ReviewOngoingUsageActivity.java | 10 ++++- .../auto/ReviewOngoingUsageAutoFragment.java | 45 +++++++++++++++++++ .../handheld/ReviewOngoingUsageFragment.java | 25 ++++++----- 3 files changed, 68 insertions(+), 12 deletions(-) create mode 100644 src/com/android/packageinstaller/permission/ui/auto/ReviewOngoingUsageAutoFragment.java diff --git a/src/com/android/packageinstaller/permission/ui/ReviewOngoingUsageActivity.java b/src/com/android/packageinstaller/permission/ui/ReviewOngoingUsageActivity.java index cba0a24b2..5568216ef 100644 --- a/src/com/android/packageinstaller/permission/ui/ReviewOngoingUsageActivity.java +++ b/src/com/android/packageinstaller/permission/ui/ReviewOngoingUsageActivity.java @@ -26,6 +26,7 @@ import androidx.annotation.NonNull; import androidx.fragment.app.FragmentActivity; import com.android.packageinstaller.DeviceUtils; +import com.android.packageinstaller.permission.ui.auto.ReviewOngoingUsageAutoFragment; import com.android.packageinstaller.permission.ui.handheld.ReviewOngoingUsageFragment; /** @@ -43,8 +44,13 @@ public final class ReviewOngoingUsageActivity extends FragmentActivity { getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS); long numMillis = getIntent().getLongExtra(Intent.EXTRA_DURATION_MILLIS, DEFAULT_MILLIS); - getSupportFragmentManager().beginTransaction().replace(android.R.id.content, - ReviewOngoingUsageFragment.newInstance(numMillis)).commit(); + if (DeviceUtils.isAuto(this)) { + getSupportFragmentManager().beginTransaction().replace(android.R.id.content, + ReviewOngoingUsageAutoFragment.newInstance(numMillis)).commit(); + } else { + getSupportFragmentManager().beginTransaction().replace(android.R.id.content, + ReviewOngoingUsageFragment.newInstance(numMillis)).commit(); + } } diff --git a/src/com/android/packageinstaller/permission/ui/auto/ReviewOngoingUsageAutoFragment.java b/src/com/android/packageinstaller/permission/ui/auto/ReviewOngoingUsageAutoFragment.java new file mode 100644 index 000000000..beeed38bf --- /dev/null +++ b/src/com/android/packageinstaller/permission/ui/auto/ReviewOngoingUsageAutoFragment.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2019 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.packageinstaller.permission.ui.auto; + +import android.app.AlertDialog; +import android.content.Intent; +import android.os.Bundle; + +import com.android.packageinstaller.permission.ui.handheld.ReviewOngoingUsageFragment; + +/** + * A dialog listing the currently uses of camera, microphone, and location. + */ +public class ReviewOngoingUsageAutoFragment extends ReviewOngoingUsageFragment { + + /** + * @return A new {@link ReviewOngoingUsageAutoFragment} + */ + public static ReviewOngoingUsageAutoFragment newInstance(long numMillis) { + ReviewOngoingUsageAutoFragment fragment = new ReviewOngoingUsageAutoFragment(); + Bundle arguments = new Bundle(); + arguments.putLong(Intent.EXTRA_DURATION_MILLIS, numMillis); + fragment.setArguments(arguments); + return fragment; + } + + @Override + protected void setNeutralButton(AlertDialog.Builder builder) { + // do nothing + } +} diff --git a/src/com/android/packageinstaller/permission/ui/handheld/ReviewOngoingUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/ReviewOngoingUsageFragment.java index b17b87f95..623d20f2a 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/ReviewOngoingUsageFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/ReviewOngoingUsageFragment.java @@ -61,7 +61,7 @@ import java.util.concurrent.TimeUnit; /** * A dialog listing the currently uses of camera, microphone, and location. */ -public final class ReviewOngoingUsageFragment extends PreferenceFragmentCompat { +public class ReviewOngoingUsageFragment extends PreferenceFragmentCompat { private @NonNull PermissionUsages mPermissionUsages; private @Nullable AlertDialog mDialog; @@ -91,7 +91,7 @@ public final class ReviewOngoingUsageFragment extends PreferenceFragmentCompat { mPermissionUsages = new PermissionUsages(getActivity()); mStartTime = Math.max(System.currentTimeMillis() - numMillis, Instant.EPOCH.toEpochMilli()); - mPermissionUsages.load(null, new String[] { CAMERA, LOCATION, MICROPHONE }, mStartTime, + mPermissionUsages.load(null, new String[]{CAMERA, LOCATION, MICROPHONE}, mStartTime, Long.MAX_VALUE, PermissionUsages.USAGE_FLAG_LAST, getActivity().getLoaderManager(), false, false, this::onPermissionUsagesLoaded, false); } @@ -142,21 +142,26 @@ public final class ReviewOngoingUsageFragment extends PreferenceFragmentCompat { } private void showDialog(@NonNull List>> usages) { - mDialog = new AlertDialog.Builder(getActivity()) + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()) .setView(createDialogView(usages)) .setPositiveButton(R.string.ongoing_usage_dialog_ok, (dialog, which) -> PermissionControllerStatsLog.write(PRIVACY_INDICATORS_INTERACTED, PRIVACY_INDICATORS_INTERACTED__TYPE__DIALOG_DISMISS, null)) - .setNeutralButton(R.string.ongoing_usage_dialog_open_settings, (dialog, which) -> { - PermissionControllerStatsLog.write(PRIVACY_INDICATORS_INTERACTED, - PRIVACY_INDICATORS_INTERACTED__TYPE__DIALOG_PRIVACY_SETTINGS, null); - startActivity(new Intent(Settings.ACTION_PRIVACY_SETTINGS).putExtra( - Intent.EXTRA_DURATION_MILLIS, TimeUnit.MINUTES.toMillis(1))); }) - .setOnDismissListener((dialog) -> getActivity().finish()) - .create(); + .setOnDismissListener((dialog) -> getActivity().finish()); + setNeutralButton(builder); + mDialog = builder.create(); mDialog.show(); } + protected void setNeutralButton(AlertDialog.Builder builder) { + builder.setNeutralButton(R.string.ongoing_usage_dialog_open_settings, (dialog, which) -> { + PermissionControllerStatsLog.write(PRIVACY_INDICATORS_INTERACTED, + PRIVACY_INDICATORS_INTERACTED__TYPE__DIALOG_PRIVACY_SETTINGS, null); + startActivity(new Intent(Settings.ACTION_PRIVACY_SETTINGS).putExtra( + Intent.EXTRA_DURATION_MILLIS, TimeUnit.MINUTES.toMillis(1))); + }); + } + private @NonNull View createDialogView( @NonNull List>> usages) { Context context = getActivity(); -- GitLab From 7a557e31b116ff2b5501e825a833a6947876afc0 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Mon, 13 May 2019 13:56:33 -0700 Subject: [PATCH 637/701] Remove code that checks appop history. PermissionUsageFragment and PermissionControllerServiceImpl both filter usages whose last usage is outside the specified interval and those with an access count of zero. The latter check always fails when appop history is disabled, and since we are not currently showing usage data, we can simply remove the check. Fixes: 132638167 Test: View permissions screens with history enabled and disabled. Change-Id: Iac72c92f508b453c453ebfd56a02baccaa43575e --- .../permission/service/PermissionControllerServiceImpl.java | 3 +-- .../permission/ui/handheld/PermissionUsageFragment.java | 3 --- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java b/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java index d11403a82..178ac6620 100644 --- a/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java +++ b/src/com/android/packageinstaller/permission/service/PermissionControllerServiceImpl.java @@ -518,8 +518,7 @@ public final class PermissionControllerServiceImpl extends PermissionControllerS for (int groupNum = 0; groupNum < numGroups; groupNum++) { GroupUsage groupUsage = appGroups.get(groupNum); - if (groupUsage.getAccessCount() <= 0 - || groupUsage.getLastAccessTime() < filterTimeBeginMillis) { + if (groupUsage.getLastAccessTime() < filterTimeBeginMillis) { continue; } if (!shouldShowPermission(this, groupUsage.getGroup())) { diff --git a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java index 4e444d726..3a302ad00 100644 --- a/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java +++ b/src/com/android/packageinstaller/permission/ui/handheld/PermissionUsageFragment.java @@ -383,9 +383,6 @@ public class PermissionUsageFragment extends SettingsWithLargeHeader implements GroupUsage groupUsage = appGroups.get(groupNum); long lastAccessTime = groupUsage.getLastAccessTime(); - if (groupUsage.getAccessCount() <= 0) { - continue; - } if (lastAccessTime == 0) { Log.w(LOG_TAG, "Unexpected access time of 0 for " + appUsage.getApp().getKey() + " " -- GitLab From 6bb4a878fdb185f6e0079e121943968771ab0f25 Mon Sep 17 00:00:00 2001 From: Heemin Seog Date: Wed, 15 May 2019 09:51:21 -0700 Subject: [PATCH 638/701] Use the default preference style for our two state preference Bug: 130348508 Test: manual Change-Id: I2d4fcd4750717e5b40d2f7b6293f990bf0074ac8 --- .../role/ui/auto/AutoDefaultAppPreference.java | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/src/com/android/packageinstaller/role/ui/auto/AutoDefaultAppPreference.java b/src/com/android/packageinstaller/role/ui/auto/AutoDefaultAppPreference.java index 0eba6b4ef..5211f006f 100644 --- a/src/com/android/packageinstaller/role/ui/auto/AutoDefaultAppPreference.java +++ b/src/com/android/packageinstaller/role/ui/auto/AutoDefaultAppPreference.java @@ -18,10 +18,10 @@ package com.android.packageinstaller.role.ui.auto; import android.content.Context; import android.text.TextUtils; -import android.util.AttributeSet; import android.view.View; import android.widget.TextView; +import androidx.core.content.res.TypedArrayUtils; import androidx.preference.PreferenceViewHolder; import androidx.preference.TwoStatePreference; @@ -30,21 +30,9 @@ import com.android.permissioncontroller.R; /** Preference used to represent apps that can be picked as a default app. */ public class AutoDefaultAppPreference extends TwoStatePreference { - public AutoDefaultAppPreference(Context context, AttributeSet attrs, - int defStyleAttr, int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); - } - - public AutoDefaultAppPreference(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - } - - public AutoDefaultAppPreference(Context context, AttributeSet attrs) { - super(context, attrs); - } - public AutoDefaultAppPreference(Context context) { - super(context); + super(context, null, TypedArrayUtils.getAttr(context, R.attr.preferenceStyle, + android.R.attr.preferenceStyle)); } @Override -- GitLab From d6cd584e4f6f1371948c02b9010c5fd12145eaf6 Mon Sep 17 00:00:00 2001 From: Joel Galenson Date: Thu, 16 May 2019 16:34:48 -0700 Subject: [PATCH 639/701] Show the accessibility usage preference when Permissions Hub is disabled. Fixes: 132909181 Test: See dialog with Permissions Hub disabled. Change-Id: I847f41525e1fc5b28a135eea6a69fd2027477de9 --- .../permission/ui/ReviewAccessibilityServicesActivity.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/com/android/packageinstaller/permission/ui/ReviewAccessibilityServicesActivity.java b/src/com/android/packageinstaller/permission/ui/ReviewAccessibilityServicesActivity.java index 20db89e10..9ed5f42c0 100644 --- a/src/com/android/packageinstaller/permission/ui/ReviewAccessibilityServicesActivity.java +++ b/src/com/android/packageinstaller/permission/ui/ReviewAccessibilityServicesActivity.java @@ -52,11 +52,6 @@ public final class ReviewAccessibilityServicesActivity extends FragmentActivity protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - if (!Utils.isPermissionsHubEnabled()) { - finish(); - return; - } - AccessibilityManager accessibilityManager = getSystemService( AccessibilityManager.class); List services = accessibilityManager -- GitLab From 2f9be5290ce3a682738a68cd337872c031a5f30d Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Thu, 16 May 2019 15:01:53 -0700 Subject: [PATCH 640/701] Clean up STOPSHIP comments for role. Bug: 132909319 Test: presubmit Change-Id: I3cc812563515b08cfc79f97df1afb658b9c8a68b --- .../packageinstaller/role/model/PreferredActivity.java | 3 ++- .../role/model/RequiredContentProvider.java | 2 +- src/com/android/packageinstaller/role/model/Role.java | 9 +++++++-- .../packageinstaller/role/model/SmsRoleBehavior.java | 5 +++-- .../role/service/RoleControllerServiceImpl.java | 4 ++-- .../role/ui/DefaultAppChildFragment.java | 1 - .../packageinstaller/role/ui/RequestRoleActivity.java | 1 - .../packageinstaller/role/ui/RequestRoleFragment.java | 1 - .../role/ui/SpecialAppAccessChildFragment.java | 1 - 9 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/com/android/packageinstaller/role/model/PreferredActivity.java b/src/com/android/packageinstaller/role/model/PreferredActivity.java index f50040029..5062e9e05 100644 --- a/src/com/android/packageinstaller/role/model/PreferredActivity.java +++ b/src/com/android/packageinstaller/role/model/PreferredActivity.java @@ -72,8 +72,9 @@ public class PreferredActivity { PackageManager packageManager = context.getPackageManager(); ComponentName packageActivity = mActivity.getQualifyingComponentForPackage( packageName, context); - // TODO: STOPSHIP: Race condition, what if packageActivity became null? Just don't crash? if (packageActivity == null) { + // We might be running into some race condition here, but we can't do anything about it. + // This should be handled by a future reconciliation started by the package change. return; } diff --git a/src/com/android/packageinstaller/role/model/RequiredContentProvider.java b/src/com/android/packageinstaller/role/model/RequiredContentProvider.java index 76fd39449..69b5a64a0 100644 --- a/src/com/android/packageinstaller/role/model/RequiredContentProvider.java +++ b/src/com/android/packageinstaller/role/model/RequiredContentProvider.java @@ -60,7 +60,7 @@ public class RequiredContentProvider extends RequiredComponent { @Nullable @Override protected String getComponentPermission(@NonNull ResolveInfo resolveInfo) { - // TODO: STOPSHIP: Which permission? Or both? + // TODO: Which permission? Or both? //return resolveInfo.providerInfo.readPermission; throw new UnsupportedOperationException(); } diff --git a/src/com/android/packageinstaller/role/model/Role.java b/src/com/android/packageinstaller/role/model/Role.java index 615480ec9..58cbf6226 100644 --- a/src/com/android/packageinstaller/role/model/Role.java +++ b/src/com/android/packageinstaller/role/model/Role.java @@ -525,7 +525,9 @@ public class Role { return false; } - // TODO: STOPSHIP: Check for disabled packages? + if (!applicationInfo.enabled) { + return false; + } if (applicationInfo.isInstantApp()) { return false; @@ -613,7 +615,10 @@ public class Role { appOp.revoke(packageName, context); } - // TODO: STOPSHIP: Revoke preferred activities? + // TODO: Revoke preferred activities? But this is unnecessary for most roles using it as + // they have fallback holders. Moreover, clearing the preferred activity might result in + // other system components listening to preferred activity change get notified for the + // wrong thing when we are removing a exclusive role holder for adding another. if (mBehavior != null) { mBehavior.revoke(this, packageName, context); diff --git a/src/com/android/packageinstaller/role/model/SmsRoleBehavior.java b/src/com/android/packageinstaller/role/model/SmsRoleBehavior.java index 2cd2080a4..606b95c84 100644 --- a/src/com/android/packageinstaller/role/model/SmsRoleBehavior.java +++ b/src/com/android/packageinstaller/role/model/SmsRoleBehavior.java @@ -66,8 +66,9 @@ public class SmsRoleBehavior implements RoleBehavior { return defaultPackageName; } - // TODO: STOPSHIP: This was the previous behavior, however this allows any third-party app - // to suddenly become the default SMS app and get the permissions. + // TODO(b/132916161): This was the previous behavior, however this may allow any third-party + // app to suddenly become the default SMS app and get the permissions, if no system default + // SMS app is available. List qualifyingPackageNames = role.getQualifyingPackagesAsUser( Process.myUserHandle(), context); return CollectionUtils.firstOrNull(qualifyingPackageNames); diff --git a/src/com/android/packageinstaller/role/service/RoleControllerServiceImpl.java b/src/com/android/packageinstaller/role/service/RoleControllerServiceImpl.java index 2c4628452..3a0b1e018 100644 --- a/src/com/android/packageinstaller/role/service/RoleControllerServiceImpl.java +++ b/src/com/android/packageinstaller/role/service/RoleControllerServiceImpl.java @@ -45,7 +45,7 @@ public class RoleControllerServiceImpl extends RoleControllerService { private static final String LOG_TAG = RoleControllerServiceImpl.class.getSimpleName(); - // TODO: STOPSHIP: Turn off debugging before we ship. + // STOPSHIP: Turn off debugging before we ship. private static final boolean DEBUG = true; private RoleManager mRoleManager; @@ -53,6 +53,7 @@ public class RoleControllerServiceImpl extends RoleControllerService { @Override public void onCreate() { super.onCreate(); + mRoleManager = getSystemService(RoleManager.class); } @@ -335,7 +336,6 @@ public class RoleControllerServiceImpl extends RoleControllerService { } if (applicationInfo != null) { - // TODO: STOPSHIP: Pass in appropriate arguments. role.revoke(packageName, dontKillApp, false, this); } diff --git a/src/com/android/packageinstaller/role/ui/DefaultAppChildFragment.java b/src/com/android/packageinstaller/role/ui/DefaultAppChildFragment.java index b64ea46f0..675f35d8c 100644 --- a/src/com/android/packageinstaller/role/ui/DefaultAppChildFragment.java +++ b/src/com/android/packageinstaller/role/ui/DefaultAppChildFragment.java @@ -217,7 +217,6 @@ public class DefaultAppChildFragment Date: Fri, 17 May 2019 13:13:18 -0700 Subject: [PATCH 641/701] Open the default home settings directly with android.settings.HOME_SETTINGS. As now we can skip the parent page in the new implementation. Bug: 132975240 Bug: 132909319 Test: adb shell am start -a android.settings.HOME_SETTINGS Change-Id: Ib42b22f31f5a101443eb80a3578ef5d66fe298be --- AndroidManifest.xml | 15 ++++--- .../role/ui/HomeSettingsActivity.java | 40 +++++++++++++++++++ 2 files changed, 50 insertions(+), 5 deletions(-) create mode 100644 src/com/android/packageinstaller/role/ui/HomeSettingsActivity.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index c2e44217c..2c77f523a 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -196,11 +196,6 @@ - - - - - + + + + + + + Date: Fri, 10 May 2019 08:27:52 -0700 Subject: [PATCH 642/701] New permissions page for app specific permissions This does not handle All permissions quite yet. This will be handled in a separate CL. This change by itself also affects the full permissions page, so it will not be submitted until other permissions CLs are approved. This CL also tries to unify the base frame for car related settings permission controller. Will need to do a separate cleanup CL for default applications. Bug: 122822231 Test: manual Change-Id: Idf946d4ce0b299e6b3a4b3b094d475a708bdfd13 --- res/layout/car_default_app_frame.xml | 55 --- res/layout/car_settings_frame.xml | 90 ++++ res/values/styles.xml | 2 +- .../auto/AutoSettingsFrameFragment.java | 121 ++++++ .../ui/ManagePermissionsActivity.java | 32 +- .../ui/auto/AutoAppPermissionsFragment.java | 388 ++++++++++++++++++ 6 files changed, 624 insertions(+), 64 deletions(-) delete mode 100644 res/layout/car_default_app_frame.xml create mode 100644 res/layout/car_settings_frame.xml create mode 100644 src/com/android/packageinstaller/auto/AutoSettingsFrameFragment.java create mode 100644 src/com/android/packageinstaller/permission/ui/auto/AutoAppPermissionsFragment.java diff --git a/res/layout/car_default_app_frame.xml b/res/layout/car_default_app_frame.xml deleted file mode 100644 index 2fe0856e3..000000000 --- a/res/layout/car_default_app_frame.xml +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - - - - - - - diff --git a/res/layout/car_settings_frame.xml b/res/layout/car_settings_frame.xml new file mode 100644 index 000000000..4381d0148 --- /dev/null +++ b/res/layout/car_settings_frame.xml @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + +