Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RxPermission: hasRequested API to check if Permission has been requested once before. #105

Merged
merged 1 commit into from
Aug 18, 2022
Merged
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
7 changes: 7 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[*.{kt,kts}]
indent_size=2
continuation_indent_size=2
insert_final_newline=true
ij_kotlin_allow_trailing_comma=true
ij_kotlin_allow_trailing_comma_on_call_site=true
disabled_rules=annotation,argument-list-wrapping,spacing-between-declarations-with-annotations,filename
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ buildscript {

dependencies {
classpath 'com.android.tools.build:gradle:7.2.2'
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10'
classpath 'com.vanniktech:gradle-code-quality-tools-plugin:0.22.0'
classpath 'com.vanniktech:gradle-maven-publish-plugin:0.21.0'
classpath 'app.cash.licensee:licensee-gradle-plugin:1.5.0'
Expand Down
6 changes: 4 additions & 2 deletions rxpermission-testing/dependencies/releaseRuntimeClasspath.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
androidx.annotation:annotation:1.4.0
io.reactivex.rxjava2:rxjava:2.2.21
org.jetbrains.kotlin:kotlin-stdlib-common:1.6.21
org.jetbrains.kotlin:kotlin-stdlib:1.6.21
org.jetbrains.kotlin:kotlin-stdlib-common:1.7.10
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.10
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.10
org.jetbrains.kotlin:kotlin-stdlib:1.7.10
org.jetbrains:annotations:13.0
org.reactivestreams:reactive-streams:1.0.3
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import io.reactivex.annotations.NonNull;
import io.reactivex.annotations.Nullable;
import io.reactivex.functions.Function;
import java.util.HashSet;
import java.util.Set;

import static com.vanniktech.rxpermission.Permission.State.GRANTED;
import static com.vanniktech.rxpermission.Permission.State.REVOKED_BY_POLICY;
Expand All @@ -20,6 +22,8 @@
public final class MockRxPermission implements RxPermission {
private final Permission[] permissions;

private final Set<String> requestedPermissions = new HashSet<>();

public MockRxPermission(final Permission... permissions) {
this.permissions = permissions;
}
Expand Down Expand Up @@ -66,11 +70,17 @@ public MockRxPermission(final Permission... permissions) {

@Nullable Permission get(@NonNull final String name) {
for (final Permission permission : permissions) {
requestedPermissions.add(name);

if (permission.name().equals(name)) {
return permission;
}
}

return null;
}

@Override public boolean hasRequested(@NonNull final String permission) {
return requestedPermissions.contains(permission);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import static android.Manifest.permission.CALL_PHONE;
import static android.Manifest.permission.CAMERA;
import static org.assertj.core.api.Java6Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

public final class MockRxPermissionTest {
Expand Down Expand Up @@ -149,6 +150,28 @@ public final class MockRxPermissionTest {
.assertResult(callPhoneGranted, cameraGranted);
}

@Test public void hasRequested() {
final MockRxPermission mockRxPermission = new MockRxPermission(callPhoneGranted, cameraGranted);
assertEquals(false, mockRxPermission.hasRequested(CALL_PHONE));
assertEquals(false, mockRxPermission.hasRequested(CAMERA));

mockRxPermission
.request(CALL_PHONE)
.test()
.assertResult(callPhoneGranted);

assertEquals(true, mockRxPermission.hasRequested(CALL_PHONE));
assertEquals(false, mockRxPermission.hasRequested(CAMERA));

mockRxPermission
.requestEach(CAMERA)
.test()
.assertResult(cameraGranted);

assertEquals(true, mockRxPermission.hasRequested(CALL_PHONE));
assertEquals(true, mockRxPermission.hasRequested(CAMERA));
}

@Test public void isGranted() {
assertThat(new MockRxPermission().isGranted(CAMERA)).isFalse();
assertThat(new MockRxPermission(cameraGranted).isGranted(CAMERA)).isTrue();
Expand Down
4 changes: 2 additions & 2 deletions rxpermission/build.gradle
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
plugins {
id("app.cash.licensee")
id("com.dropbox.dependency-guard")
id("com.android.library")
id("org.jetbrains.kotlin.android")
}

apply plugin: 'com.android.library'

licensee {
allow("Apache-2.0")
allow("CC0-1.0")
Expand Down
6 changes: 4 additions & 2 deletions rxpermission/dependencies/releaseRuntimeClasspath.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
androidx.annotation:annotation:1.4.0
io.reactivex.rxjava2:rxjava:2.2.21
org.jetbrains.kotlin:kotlin-stdlib-common:1.6.21
org.jetbrains.kotlin:kotlin-stdlib:1.6.21
org.jetbrains.kotlin:kotlin-stdlib-common:1.7.10
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.10
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.10
org.jetbrains.kotlin:kotlin-stdlib:1.7.10
org.jetbrains:annotations:13.0
org.reactivestreams:reactive-streams:1.0.3
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import android.annotation.TargetApi;
import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import androidx.annotation.ChecksSdkIntAtLeast;
import io.reactivex.Observable;
import io.reactivex.ObservableSource;
Expand All @@ -13,9 +14,14 @@
import io.reactivex.functions.Function;
import io.reactivex.subjects.PublishSubject;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.jetbrains.annotations.NotNull;

import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.os.Build.VERSION.SDK_INT;
Expand All @@ -29,6 +35,8 @@ public final class RealRxPermission implements RxPermission {
static final Object TRIGGER = new Object();
static RealRxPermission instance;

static final String PREF_REQUESTED_PERMISSIONS = "requested-permissions";

/**
* @param context any context
* @return a Singleton instance of this class
Expand Down Expand Up @@ -165,6 +173,15 @@ public static RealRxPermission getInstance(final Context context) {
}

void startShadowActivity(final String[] permissions) {
final SharedPreferences sharedPreferences = getSharedPreferences();
final Set<String> requestedPermission = new HashSet<>(sharedPreferences.getStringSet(PREF_REQUESTED_PERMISSIONS, Collections.emptySet()));
requestedPermission.addAll(Arrays.asList(permissions));

sharedPreferences
.edit()
.putStringSet(PREF_REQUESTED_PERMISSIONS, requestedPermission)
.apply();

ShadowActivity.start(application, permissions);
}

Expand Down Expand Up @@ -201,4 +218,14 @@ void onRequestPermissionsResult(@NonNull final int[] grantResults, @NonNull fina
void cancelPermissionsRequests() {
currentPermissionRequests.clear();
}

@Override public boolean hasRequested(@NotNull String permission) {
final SharedPreferences sharedPreferences = getSharedPreferences();
final Set<String> requestedPermission = sharedPreferences.getStringSet(PREF_REQUESTED_PERMISSIONS, Collections.emptySet());
return requestedPermission.contains(permission);
}

private SharedPreferences getSharedPreferences() {
return application.getSharedPreferences("RxPermission", Context.MODE_PRIVATE);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.vanniktech.rxpermission

import io.reactivex.Observable
import io.reactivex.Single
import io.reactivex.annotations.CheckReturnValue

interface RxPermission {
/** Requests a single permission. */
@CheckReturnValue fun request(permission: String): Single<Permission?>

/** Requests multiple permissions. */
@CheckReturnValue fun requestEach(vararg permissions: String): Observable<Permission?>

/** Returns true when the given permission is granted. */
@CheckReturnValue fun isGranted(permission: String): Boolean

/** Returns true when the given permission is revoked by a policy. */
@CheckReturnValue fun isRevokedByPolicy(permission: String): Boolean

/** Returns tue when the given permission has been request at least once using either [request] or [requestEach]. */
@CheckReturnValue fun hasRequested(permission: String): Boolean
}
4 changes: 2 additions & 2 deletions sample/dependencies/releaseRuntimeClasspath.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ androidx.viewpager:viewpager:1.0.0
com.google.guava:listenablefuture:1.0
io.reactivex.rxjava2:rxjava:2.2.21
org.jetbrains.kotlin:kotlin-stdlib-common:1.7.10
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.6.0
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.0
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.10
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.10
org.jetbrains.kotlin:kotlin-stdlib:1.7.10
org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.1
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.6.1
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
package com.vanniktech.rxpermission.sample;

import android.Manifest;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.vanniktech.rxpermission.Permission;
import com.vanniktech.rxpermission.RealRxPermission;
import com.vanniktech.rxpermission.RxPermission;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.vanniktech.rxpermission.RealRxPermission;
import com.vanniktech.rxpermission.RxPermission;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.functions.Consumer;

public class MainActivity extends AppCompatActivity {
private static final String PERMISSION = Manifest.permission.CAMERA;
RxPermission rxPermission;

@NonNull final CompositeDisposable compositeDisposable = new CompositeDisposable();
Expand All @@ -24,17 +23,18 @@ public class MainActivity extends AppCompatActivity {
rxPermission = RealRxPermission.getInstance(getApplication());

setContentView(R.layout.activity_main);
updateTextView();

findViewById(R.id.enableCamera).setOnClickListener(v -> compositeDisposable.add(rxPermission.requestEach(
PERMISSION)
.subscribe(granted -> {
updateTextView();
Toast.makeText(this, granted.toString(), Toast.LENGTH_LONG).show();
})));
}

findViewById(R.id.enableCamera).setOnClickListener(new View.OnClickListener() {
@Override public void onClick(final View v) {
compositeDisposable.add(rxPermission.requestEach(Manifest.permission.CAMERA)
.subscribe(new Consumer<Permission>() {
@Override public void accept(final Permission granted) throws Exception {
Toast.makeText(MainActivity.this, granted.toString(), Toast.LENGTH_LONG).show();
}
}));
}
});
@SuppressLint("SetTextI18n") private void updateTextView() {
this.<TextView>findViewById(R.id.textView).setText("Has requested: " + rxPermission.hasRequested(PERMISSION));
}

@Override protected void onDestroy() {
Expand Down
26 changes: 21 additions & 5 deletions sample/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
@@ -1,10 +1,26 @@
<Button xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/enableCamera"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="16dp"
android:text="Enable camera"
tools:ignore="HardcodedText"
/>
android:orientation="vertical"
>
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="16dp"
tools:ignore="HardcodedText"
/>
<Button
android:id="@+id/enableCamera"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="16dp"
android:text="Enable camera"
tools:ignore="HardcodedText"
/>
</LinearLayout>