Skip to content

Commit

Permalink
RxPermission: hasRequested API to check if Permission has been reques…
Browse files Browse the repository at this point in the history
…ted once before. (#105)
  • Loading branch information
vanniktech authored Aug 18, 2022
1 parent bba8937 commit 351b2e8
Show file tree
Hide file tree
Showing 13 changed files with 139 additions and 49 deletions.
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>

0 comments on commit 351b2e8

Please sign in to comment.