Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions PermissionController/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,12 @@
android:permission="android.permission.WRITE_SECURE_SETTINGS"
android:exported="true" />

<activity
android:name="com.android.permissioncontroller.privacy.LocationIndicatorActivity"
android:theme="@style/Theme.PermissionController.Settings.FilterTouches"
android:permission="android.permission.WRITE_SECURE_SETTINGS"
android:exported="true" />

<activity
android:name="com.android.permissioncontroller.ext.aauto.AndroidAutoConfigActivity"
android:theme="@style/Theme.PermissionController.Settings.FilterTouches"
Expand Down
5 changes: 5 additions & 0 deletions PermissionController/res/navigation/nav_graph.xml
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,11 @@
android:name="com.android.permissioncontroller.cscopes.ContactScopesWrapperFragment"
android:label="ContactScopes"/>

<fragment
android:id="@+id/location_indicator"
android:name="com.android.permissioncontroller.privacy.LocationIndicatorWrapperFragment"
android:label="LocationIndicator"/>


<fragment
android:id="@+id/android_auto_config"
Expand Down
5 changes: 5 additions & 0 deletions PermissionController/res/values/strings_ext.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,9 @@
<string name="scopes_btn_remove_scope">Remove</string>

<string name="action_proceed">Proceed</string>

<string name="location_indicator">Location indicator</string>
<string name="location_indicator_footer">When enabled, the standard privacy indicator will not show when the app is using location. It is assumed that the app will always be tracking your location. Location usage will still be logged.</string>
<string name="hide_location_indicator_title">Hide location indicator</string>
<string name="hide_location_indicator_toast">Changes will take effect the next time the app requests location access.</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -1046,6 +1046,7 @@ public void onClick(View widget) {

public static final int REQ_CODE_SETUP_STORAGE_SCOPES = 100;
public static final int REQ_CODE_SETUP_CONTACT_SCOPES = 101;
public static final int REQ_CODE_SETUP_LOCATION_INDICATOR = 102;

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Expand All @@ -1071,6 +1072,11 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
return;
}

if (requestCode == REQ_CODE_SETUP_LOCATION_INDICATOR) {
setResultAndFinish();
return;
}

if (requestCode != APP_PERMISSION_REQUEST_CODE
&& requestCode != PHOTO_PICKER_REQUEST_CODE) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import android.os.UserHandle
import android.widget.Button
import com.android.permissioncontroller.cscopes.ContactScopesLinks
import com.android.permissioncontroller.permission.ui.GrantPermissionsActivity
import com.android.permissioncontroller.privacy.LocationIndicatorLinks
import com.android.permissioncontroller.sscopes.StorageScopesLinks

abstract class ExtraPermissionLink {
Expand All @@ -29,6 +30,7 @@ abstract class ExtraPermissionLink {
private val allExtraPermissionLinks = arrayOf(
StorageScopesLinks,
ContactScopesLinks,
LocationIndicatorLinks,
)

fun getExtraPermissionLink(ctx: Context, packageName: String, user: UserHandle, groupName: String): ExtraPermissionLink? {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.android.permissioncontroller.privacy

import com.android.permissioncontroller.R
import com.android.permissioncontroller.ext.PackageExtraConfigActivity

class LocationIndicatorActivity : PackageExtraConfigActivity() {
override fun getNavGraphStart() = R.id.location_indicator
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package com.android.permissioncontroller.privacy

import android.content.Intent
import android.content.pm.GosPackageState
import android.content.pm.GosPackageStateFlag
import android.net.Uri
import android.os.Bundle
import android.widget.Toast
import com.android.permissioncontroller.R
import com.android.permissioncontroller.ext.PackageExtraConfigFragment
import com.android.permissioncontroller.ext.addOrRemove
import com.android.permissioncontroller.ext.createFooterPreference
import com.android.settingslib.widget.FooterPreference
import com.android.settingslib.widget.MainSwitchPreference

class LocationIndicatorFragment : PackageExtraConfigFragment() {
lateinit var mainSwitch: MainSwitchPreference
lateinit var footer: FooterPreference

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

mainSwitch = MainSwitchPreference(context_).apply {
setTitle(R.string.hide_location_indicator_title)
setOnPreferenceChangeListener { _, newValue ->
val editor = GosPackageState.edit(pkgName, context_.user)
editor.setFlagState(
GosPackageStateFlag.HIDE_LOCATION_INDICATOR,
newValue as Boolean
)
val result = editor.apply()
if (result) {
Toast.makeText(
context_,
R.string.hide_location_indicator_toast,
Toast.LENGTH_LONG
).show()
}
result
}
}

footer = createFooterPreference()

update()
}

override fun getTitle(): CharSequence = getText(R.string.location_indicator)

override fun update() {
val state = getGosPackageState()
mainSwitch.isChecked = state.hasFlag(GosPackageStateFlag.HIDE_LOCATION_INDICATOR)
addOrRemove(mainSwitch, true)

footer.setSummary(R.string.location_indicator_footer)
footer.setLearnMoreAction {
val link = "https://grapheneos.org/features#location-data-access-indicator"
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(link)))
}
addOrRemove(footer, true)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package com.android.permissioncontroller.privacy

import android.Manifest
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.pm.ApplicationInfo
import android.content.pm.GosPackageState
import android.os.UserHandle
import android.widget.Button
import com.android.permissioncontroller.R
import com.android.permissioncontroller.permission.ui.GrantPermissionsActivity
import com.android.permissioncontroller.permission.ui.handheld.ExtraPermissionLink

object LocationIndicatorLinks : ExtraPermissionLink() {

override fun isVisible(
ctx: Context,
groupName: String,
packageName: String,
user: UserHandle
): Boolean {
// dont show on permission dialog requests or system apps
val inPermissionDialog = ctx is GrantPermissionsActivity
return groupName == Manifest.permission_group.LOCATION
&& !inPermissionDialog
&& !isSystemApp(ctx, user, packageName)
}

override fun setupDialogButton(button: Button) {
button.setText(R.string.location_indicator)
}

override fun onDialogButtonClick(activity: GrantPermissionsActivity, packageName: String) {
val intent = createConfigActivityIntent(packageName)
@Suppress("DEPRECATION")
activity.startActivityForResult(
intent,
GrantPermissionsActivity.REQ_CODE_SETUP_LOCATION_INDICATOR
)
}

override fun isAllowPermissionSettingsButtonBlocked(
ctx: Context, packageName: String,
user: UserHandle
): Boolean {
return false
}

override fun onAllowPermissionSettingsButtonClick(ctx: Context) {
}

override fun getSettingsDeniedRadioButtonSuffix(
ctx: Context,
packageState: GosPackageState
): String? {
return null
}

override fun getSettingsLinkText(ctx: Context): CharSequence {
return ctx.getText(R.string.location_indicator)
}

override fun onSettingsLinkClick(ctx: Context, packageName: String, user: UserHandle) {
val intent = createConfigActivityIntent(packageName)
ctx.startActivityAsUser(intent, user)
}

fun createConfigActivityIntent(targetPkg: String): Intent {
val i = Intent()
val pkg = "com.android.permissioncontroller"
i.setComponent(ComponentName.createRelative(pkg, ".privacy.LocationIndicatorActivity"))
i.putExtra(Intent.EXTRA_PACKAGE_NAME, targetPkg)
return i
}

fun isSystemApp(ctx: Context, userHandle: UserHandle, packageName: String): Boolean {
return try {
val appInfo = ctx.packageManager.getApplicationInfoAsUser(
packageName,
0,
userHandle
)
(appInfo.flags and ApplicationInfo.FLAG_SYSTEM) != 0 ||
(appInfo.flags and ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0
} catch (_: Exception) {
false
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.android.permissioncontroller.privacy

import androidx.preference.PreferenceFragmentCompat
import com.android.permissioncontroller.permission.ui.handheld.PermissionsCollapsingToolbarBaseFragment

class LocationIndicatorWrapperFragment : PermissionsCollapsingToolbarBaseFragment() {
override fun createPreferenceFragment(): PreferenceFragmentCompat = LocationIndicatorFragment()
}